Nette Documentation Preview

syntax
Мултипликатор: динамични компоненти
***********************************

Инструмент за динамично създаване на интерактивни компоненти.

Нека да започнем с типичен проблем: имаме списък с продукти в сайт за електронна търговия и искаме да придружим всеки продукт с формуляр за *добавяне в количката*. Един от начините е да обхванете целия списък в един формуляр. По-удобен начин е да използвате [api:Nette\Application\UI\Multiplier].

Multiplier ви позволява да дефинирате фабрика за няколко компонента. Той се основава на принципа на вложените компоненти - всеки компонент, който наследява от [api:Nette\ComponentModel\Container], може да съдържа други компоненти.

Вижте [модела на компонента |components#Components in Depth] в документацията.

Multiplier е родителски компонент, който може динамично да създава своите деца, като използва обратната връзка, предадена в конструктора. Вижте пример:

```php
protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function () {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('amount', 'Amount:')
			->setRequired();
		$form->addSubmit('send', 'Add to cart');
		return $form;
	});
}
```

В шаблона можем да покажем формуляр за всеки продукт - и всеки формуляр ще бъде уникален компонент.

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

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

Аргументът, предаден в тага `{control}`, гласи:

1. вземете компонента `shopForm`
2. да се върне при своя наследник `$item->id`

При първото извикване на **1.** компонентът `shopForm` все още не съществува, затова се извиква методът `createComponentShopForm`, за да се създаде. След това се извиква анонимна функция, предадена като параметър на Multiplier, и се създава форма.

В следващите итерации на `foreach` методът `createComponentShopForm` вече не се извиква, защото компонентът вече съществува. Но тъй като препращаме към друг потомък (`$item->id` варира между итерациите), анонимната функция се извиква отново и се създава нова форма.

Последното нещо, което трябва да се направи, е да се уверим, че формулярът действително добавя правилния продукт към количката, тъй като в сегашното състояние всички формуляри са еднакви и не можем да разграничим към кои продукти принадлежат. За да направим това, можем да използваме свойството на класа Multiplier (и като цяло всеки метод за фабрика на компоненти в рамката Nette), че всеки метод за фабрика на компоненти получава името на създадения компонент като първи аргумент. В нашия случай това ще бъде `$item->id`, което е точно това, от което се нуждаем, за да разграничаваме отделните продукти. Всичко, което трябва да направите, е да промените кода за създаване на формуляра:

```php
protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function ($itemId) {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('amount', 'Количество:')
			->setRequired();
		$form->addHidden('itemId', $itemId);
		$form->addSubmit('send', 'Добавить в корзину');
		return $form;
	});
}
```

Мултипликатор: динамични компоненти

Инструмент за динамично създаване на интерактивни компоненти.

Нека да започнем с типичен проблем: имаме списък с продукти в сайт за електронна търговия и искаме да придружим всеки продукт с формуляр за добавяне в количката. Един от начините е да обхванете целия списък в един формуляр. По-удобен начин е да използвате Nette\Application\UI\Multiplier.

Multiplier ви позволява да дефинирате фабрика за няколко компонента. Той се основава на принципа на вложените компоненти – всеки компонент, който наследява от Nette\ComponentModel\Container, може да съдържа други компоненти.

Вижте модела на компонента в документацията.

Multiplier е родителски компонент, който може динамично да създава своите деца, като използва обратната връзка, предадена в конструктора. Вижте пример:

protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function () {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('amount', 'Amount:')
			->setRequired();
		$form->addSubmit('send', 'Add to cart');
		return $form;
	});
}

В шаблона можем да покажем формуляр за всеки продукт – и всеки формуляр ще бъде уникален компонент.

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

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

Аргументът, предаден в тага {control}, гласи:

  1. вземете компонента shopForm
  2. да се върне при своя наследник $item->id

При първото извикване на 1. компонентът shopForm все още не съществува, затова се извиква методът createComponentShopForm, за да се създаде. След това се извиква анонимна функция, предадена като параметър на Multiplier, и се създава форма.

В следващите итерации на foreach методът createComponentShopForm вече не се извиква, защото компонентът вече съществува. Но тъй като препращаме към друг потомък ($item->id варира между итерациите), анонимната функция се извиква отново и се създава нова форма.

Последното нещо, което трябва да се направи, е да се уверим, че формулярът действително добавя правилния продукт към количката, тъй като в сегашното състояние всички формуляри са еднакви и не можем да разграничим към кои продукти принадлежат. За да направим това, можем да използваме свойството на класа Multiplier (и като цяло всеки метод за фабрика на компоненти в рамката Nette), че всеки метод за фабрика на компоненти получава името на създадения компонент като първи аргумент. В нашия случай това ще бъде $item->id, което е точно това, от което се нуждаем, за да разграничаваме отделните продукти. Всичко, което трябва да направите, е да промените кода за създаване на формуляра:

protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function ($itemId) {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('amount', 'Количество:')
			->setRequired();
		$form->addHidden('itemId', $itemId);
		$form->addSubmit('send', 'Добавить в корзину');
		return $form;
	});
}