Nette Documentation Preview

syntax
Mnożnik: składniki dynamiczne
*****************************

Narzędzie do dynamicznego tworzenia interaktywnych komponentów .[perex]

Zacznijmy od typowego przykładu: miejmy listę przedmiotów w sklepie internetowym, a dla każdego przedmiotu chcemy wypisać formularz dodawania przedmiotu do koszyka. Jedną z możliwych opcji jest zawinięcie całego listingu w jeden formularz. Jednak znacznie wygodniejszy sposób oferuje [api:Nette\Application\UI\Multiplier].

Mnożnik pozwala na wygodne zdefiniowanie fabryki dla wielu komponentów. Działa na zasadzie zagnieżdżonych komponentów - każdy komponent dziedziczący po [api:Nette\ComponentModel\Container] może zawierać inne komponenty.

Zobacz rozdział o [modelu komponentów |components#Advanced-Use-of-Components] w dokumentacji lub [wykład Honzy Tvrdíka |https://www.youtube.com/watch?v=8y3LLexWu-I]. .[tip]

Istotą Multiplier jest to, że działa jako rodzic, który może dynamicznie tworzyć swoje dzieci za pomocą wywołania zwrotnego przekazanego w konstruktorze. Zobacz przykład:

```php
protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function () {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('count', 'Počet zboží:')
			->setRequired();
		$form->addSubmit('send', 'Přidat do košíku');
		return $form;
	});
}
```

Teraz możemy po prostu mieć formularz renderowany dla każdego elementu w szablonie - i każdy będzie naprawdę unikalnym komponentem.

```latte
{foreach $items as $item}
	<h2>{$item->title}</h2>
	{$item->description}

	{control "shopForm-$item->id"}
{/foreach}
```

Argument przekazywany w znaczniku `{control}` ma format mówiący:

1. zdobądź komponent `shopForm`
2. i uzyskać od niej dziecko `$item->id`

Przy pierwszym wywołaniu punktu **1.**, `shopForm` jeszcze nie istnieje, więc wywoływana jest jego fabryka `createComponentShopForm` Fabryka danej formy - którą jest anonimowa funkcja, którą przekazaliśmy Multiplierowi w konstruktorze - jest następnie wywoływana na uzyskanym komponencie (instancji Multiplera).

W kolejnej iteracji foreache metoda `createComponentShopForm` nie zostanie już wywołana (komponent istnieje), ale ponieważ szukamy jego drugiego potomka (`$item->id` będzie inny w każdej iteracji), funkcja anonimowa zostanie ponownie wywołana i zwróci nowy formularz.

Pozostaje tylko zadbać o to, aby formularz faktycznie dodawał do naszego koszyka przedmioty, które posiada - obecnie formularz jest dokładnie taki sam dla każdego przedmiotu. Cechą Multiplier (i w ogóle każdej fabryki komponentów w Nette Framework), która nam pomaga jest to, że każda fabryka dostaje jako pierwszy argument nazwę tworzonego komponentu. W naszym przypadku będzie to `$item->id`, czyli dokładnie taka informacja, jakiej potrzebujemy. Musimy więc tylko lekko zmodyfikować tworzenie formularza:

```php
protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function ($itemId) {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('count', 'Počet zboží:')
			->setRequired();
		$form->addHidden('itemId', $itemId);
		$form->addSubmit('send', 'Přidat do košíku');
		return $form;
	});
}
```

Mnożnik: składniki dynamiczne

Narzędzie do dynamicznego tworzenia interaktywnych komponentów

Zacznijmy od typowego przykładu: miejmy listę przedmiotów w sklepie internetowym, a dla każdego przedmiotu chcemy wypisać formularz dodawania przedmiotu do koszyka. Jedną z możliwych opcji jest zawinięcie całego listingu w jeden formularz. Jednak znacznie wygodniejszy sposób oferuje Nette\Application\UI\Multiplier.

Mnożnik pozwala na wygodne zdefiniowanie fabryki dla wielu komponentów. Działa na zasadzie zagnieżdżonych komponentów – każdy komponent dziedziczący po Nette\ComponentModel\Container może zawierać inne komponenty.

Zobacz rozdział o modelu komponentów w dokumentacji lub wykład Honzy Tvrdíka.

Istotą Multiplier jest to, że działa jako rodzic, który może dynamicznie tworzyć swoje dzieci za pomocą wywołania zwrotnego przekazanego w konstruktorze. Zobacz przykład:

protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function () {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('count', 'Počet zboží:')
			->setRequired();
		$form->addSubmit('send', 'Přidat do košíku');
		return $form;
	});
}

Teraz możemy po prostu mieć formularz renderowany dla każdego elementu w szablonie – i każdy będzie naprawdę unikalnym komponentem.

{foreach $items as $item}
	<h2>{$item->title}</h2>
	{$item->description}

	{control "shopForm-$item->id"}
{/foreach}

Argument przekazywany w znaczniku {control} ma format mówiący:

  1. zdobądź komponent shopForm
  2. i uzyskać od niej dziecko $item->id

Przy pierwszym wywołaniu punktu 1., shopForm jeszcze nie istnieje, więc wywoływana jest jego fabryka createComponentShopForm Fabryka danej formy – którą jest anonimowa funkcja, którą przekazaliśmy Multiplierowi w konstruktorze – jest następnie wywoływana na uzyskanym komponencie (instancji Multiplera).

W kolejnej iteracji foreache metoda createComponentShopForm nie zostanie już wywołana (komponent istnieje), ale ponieważ szukamy jego drugiego potomka ($item->id będzie inny w każdej iteracji), funkcja anonimowa zostanie ponownie wywołana i zwróci nowy formularz.

Pozostaje tylko zadbać o to, aby formularz faktycznie dodawał do naszego koszyka przedmioty, które posiada – obecnie formularz jest dokładnie taki sam dla każdego przedmiotu. Cechą Multiplier (i w ogóle każdej fabryki komponentów w Nette Framework), która nam pomaga jest to, że każda fabryka dostaje jako pierwszy argument nazwę tworzonego komponentu. W naszym przypadku będzie to $item->id, czyli dokładnie taka informacja, jakiej potrzebujemy. Musimy więc tylko lekko zmodyfikować tworzenie formularza:

protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function ($itemId) {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('count', 'Počet zboží:')
			->setRequired();
		$form->addHidden('itemId', $itemId);
		$form->addSubmit('send', 'Přidat do košíku');
		return $form;
	});
}