Nastavení proměnné do template z createComponent

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

Zdravím,
snažím se přijít na způsob (best practice) jak dostat informace do šablony přes funkci createComponent(). Zdůvodnění: Když načtu data z DB chci k jednotlivým řádkům přiřadit checkbox pro vybrání. Zde je dosavadní kód:

protected function createComponentPostsForm()
{
	$form = new Form;
	$form->setTranslator($this->translator);

	$filter = isset($this->getSession('posts')->sort) ? $this->getSession('posts')->sort : 'active';
	$action = ($filter == 'removed') ? 'Delete' : 'Remove';

	$form->addSubmit('action', $action);
	$form->addCheckbox('selectAll');

	try {
		$posts = $this->posts->getPosts($filter);
		$CheckboxContainer = $form->addContainer('posts');

		foreach ($posts as $post) {
			$post['checkbox'] = $CheckboxContainer->addCheckbox($post->id));
			$this->postsList[] = $post;
		}

	} catch (\Nette\Application\ApplicationException $e) {
		$form->addError($this->translator->translate($e->getMessage()));
	}

	$form->onSuccess[] = function (Form $form) {

	};

	return $form;
}

Proměnná $postsList je definovaná v presenteru jako public a poté z ní v latte čtu klasicky {foreach $form->parent->postsList as $post}.
Ovšem Nette 2.1 bohužel/bohudík stanovilo ActiveRow jako read-only takže:

$post['checkbox'] = $CheckboxContainer->addCheckbox($post->id));

nejde. Jestli má někdo zkušenosti, nebo nápady jak vyřešit tuto situaci jsem jedno ucho…

David Matějka
Moderator | 6445
+
0
-

1. do action* metode dej

$this->posts = $this->posts->getPosts($filter);

2. v create component prochazej $this->posts
3. v render metode dej

$this->template->posts = $this->posts

4. v sablone:

{form postsForm}
	{foreach $posts as $post}
		{input post-{$post->id}} {* tady nevim jestli to presne tohle sezere *}
	{/foreach}
{/form}
VojtaSim
Člen | 55
+
0
-

Díky za odpověď. No ale problém bude v tom, když zavolám handleSort(), která mění obsah proměnné $filter tak to nebude mít žádný účinek, protože handle se vykonává až po action. Takže to načítání z DB nechám v createComponent() a potom v render to dám do šablony.

VojtaSim
Člen | 55
+
0
-

matej21 napsal(a):
{input post-{$post->id}} {* tady nevim jestli to presne tohle sezere *}
\--

Nesežere
Component name must be non-empty alphanumeric string, 'post-33' given.

David Matějka
Moderator | 6445
+
0
-

k tomu, kde data vytvaret:
s tim muzes mit problem, kdybys je vybiral az v createComponent, jelikoz kdyz form nezpracovavas, ale pouze zobrazujes, tak se nacita az ve chvili, kdy se vykresluje (az v sablone, po vsech render metodach) – v render metode by tedy ta data nebyla dostupna..
reseni: pripravit v action vysledek, ktery bude lazy a bude se nechat setridit – v pripade nette\database bude stacit tam ulozit selection a pak zavolat ->order(…).
reseni 2 (nejhorsi): v render metode dat $this['postsForm'] – to zajisti inicializaci komponenty a tedy i nacteni dat.
reseni 3 (asi nej) – vyber dat dát do metody, ktera si to pri prvni pozadavku ulozi do clenske promenne – v pripade, ze budes form pouze vykreslovat, pozada o to render metoda jako prvni, v pripade, ze se bude form zpracovavat, pozada o to prvni createComponent metoda

k sablone:
mam tam preklep, misto posts v inputu mam jen post (musi to byt stejne jako nazev kontejneru), tak to zkus, treba uz to pude. kdyz ne, tak zkus:

{form postsForm}
    {formContainer post}
    {foreach $posts as $post}
        {input $post->id}
    {/foreach}
    {/formContainer}
{/form}

nebo

{form postsForm}
    {foreach $posts as $post}
        {var $key = 'post-' . $post->id}
        {input $key}
    {/foreach}
{/form}

Editoval matej21 (20. 12. 2013 18:31)