Grido, zivotni cyklus presenteru – handlerXXX je nekdy zavolan drive, nez createComponentXXX

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
chaky
Člen | 22
+
0
-

Pouzivam ve sve aplikaci Grido. Mam v nem na radcich definovane (tlacitka) akce, ktere posilaji signal do handleru handleGridoOperations. A take tam mam hromadne akce, ktere se aktivuji vyberem checkboxu na jednotlivych radcich a vyberem prislusne akce roletkou dole v tabulce generovane Grodo komponentou.

Dokud jsem aplikaci testoval jako ne-ajaxovou, tak vse chodilo jak jsem ocekaval. Po zapnuti ajaxu jsem zjistil, ze bez problemu funguje jen ten pripad, kdy se pouziji ty me tlacitka – tedy jen pokud se k nim do URL requestu nepribali treba nejaky filter, nebo ordering z Grido.

Link tech tlacitek generuju v presenteru vlastnim rendererem:

$link = $this->link('GridoOperations!', ['operation' => 'assignLine', 'id' => $item->idPact]);

Kliknuti na tento link tkzv. „z cisteho stolu“ vyprodukuje takovouto URL:

http://localhost/mainApp/shared-line/show/4609?operation=assignLine&idSharedLine=1&last_link=66kv2&do=GridoOperations

Operace assignLine, provede nejake zmeny v DB a ty se po redrawControl() projevi prekreslenim prislusnych snippet oblasti, vcetne radku v Grido. Debuggerem jsem si nechal zalogovat volani metod presenteru. Probehly v tomto poradi:

[2017-08-29 19-18-21] App\Presenters\SharedLinePresenter::actionShow
[2017-08-29 19-18-21] App\Presenters\SharedLinePresenter::handleGridoOperations
[2017-08-29 19-18-21] App\Presenters\SharedLinePresenter::createComponentAllPactsGrid
[2017-08-29 19-18-21] App\Presenters\SharedLinePresenter::renderShow

Nyni si v prohlizeci v te Grido tabulce udelam nejaky filtr, napr. reknu ze chci mit zobrazeny jen radky, ktere ve sloupci ‚distributors‘ obsahuji ‚%1-vs%‘. A nasledne opet kliknu na tlacitko s odeslanim signalu. Vytvori se nasledujici URL:

http://localhost/mainApp/shared-line/show/1?operation=removeLine&idSharedLine=1&last_link=v9pjj&allPactsGrid-filter%5Bdistributors%5D=1-vs&do=GridoOperations

Provede se zmena v DB. Prekresli se snippet oblasti, ale neprekresli se ovlivnene radky v Grido. Ze zalogovaneho debugu je zrejme proc – nejprve se totiz vytvori komponenta Grido a az potom se zavola handler, ktery provede zmenu v DB:

[2017-08-29 19-23-49] App\Presenters\SharedLinePresenter::actionShow
[2017-08-29 19-23-49] App\Presenters\SharedLinePresenter::createComponentAllPactsGrid
[2017-08-29 19-23-49] App\Presenters\SharedLinePresenter::handleGridoOperations
[2017-08-29 19-23-49] App\Presenters\SharedLinePresenter::actionRemoveLine
[2017-08-29 19-23-49] App\Presenters\SharedLinePresenter::renderShow

Proc se to tak deje? Myslel jsem, ze handlery se volaji vzdy hned po actionXXX.

David Matějka
Moderator | 6445
+
0
-

komponenta se vytvari ve chvili, kdy je potreba. neni proto dobre spolehat na to, kdy to bude (pokud neprovedu jeji explicitni inicializaci). to, ze se vytvorila hned po action je kvuli temto radkum

spise bys tedy mel zjistit, proc ta komponenta nacita tak brzo data – tzn kde a proc dojde k nacteni dat z db

chaky
Člen | 22
+
0
-

Aha, priznam se, ze mne vlastne ani vubec nenapadlo delat to jinak, nez ze ve chvili, kdy je zavolan createComponentXX() … ostatne takhle jsem to ostatne odkoukal primo z Grido examples, kde se vzdy ve chvili, kdy je zavolan createComponent() udela:

protected function createComponentMainGrid($name) {
	$grid = new Grid($this, $name);
	grid->model = ... nacteni dat z DB ...

	... vydefinovani sloupcu, atp. ...
	$grid->addColumn...

	$grid->setExport();
}

Jak bych mel tedy tu komponentu obsluhovat?

chaky
Člen | 22
+
0
-

Aha, tak uz vim :) Doposud jsem vzdy jako model u toho Grido pouzival TableSelection:

$grid->model = $this->database->table($tbname);

V tomto pripade vsak byl ten select trochu komplikovanejsi a tak jsem bezelstne pouzil neco trochu jineho:

$grid->model = $this->database->query($sql)->fetchAll();

Tim se v dobe vyroby komponenty uvnitr createComponent() vytvoril Array, ktery obsahoval data z doby, nez doslo ke zmene DB.

Vyresil jsem to ted tedy tak, ze jsem ten SQL ulozil do view. Ve chvili, kdy do modelu predavam TableSelection, tak je zrejme vse tak jak potrebuju:

$grid->model = $this->database->table($tbname)->where('idTariff = ?', $this->sharedLine->idTariff);

Nicmene musim priznat, ze kdybych skutecne musel pracovat s Array a ne s DB, tak bych byl opravdu bezradny, protoze mi neni jasne jak nakrmit to Grido az v dobe, kdy probehnul handler…