Nette Documentation Preview

syntax
Multiplier: dinamične komponente
********************************

.[perex]
Orodje za dinamično ustvarjanje interaktivnih komponent

Izhajajmo iz tipičnega primera: imejmo seznam blaga v spletni trgovini, pri čemer bomo pri vsakem želeli izpisati obrazec za dodajanje blaga v košarico. Ena od možnih variant je oviti celoten izpis v en obrazec. Veliko udobnejši način pa nam ponuja [api:Nette\Application\UI\Multiplier].

Multiplier omogoča udobno definiranje tovarniške metode za več komponent. Deluje na principu ugnezdenih komponent - vsaka komponenta, ki deduje od [api:Nette\ComponentModel\Container], lahko vsebuje druge komponente.

.[tip]
Glej poglavje o [komponentnem modelu |components#Komponente v globino] v dokumentaciji ali [predavanje Honze Tvrdíka|https://www.youtube.com/watch?v=8y3LLexWu-I].

Bistvo Multiplierja je, da nastopa v vlogi starša, ki si svoje potomce lahko ustvarja dinamično s pomočjo povratnega klica (callback), predanega v konstruktorju. Glej primer:

```php
protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function () {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('count', 'Število kosov:')
			->setRequired();
		$form->addSubmit('send', 'Dodaj v košarico');
		return $form;
	});
}
```

Zdaj lahko v predlogi enostavno pri vsakem blagu pustimo izrisati obrazec - in vsak bo resnično edinstvena komponenta.

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

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

Argument, predan v znački `{control}`, je v formatu, ki pravi:

1. pridobi komponento `shopForm`
2. in iz nje pridobi potomca `$item->id`

Pri prvem klicu točke **1.** `shopForm` še ne obstaja, zato se pokliče njegova tovarna `createComponentShopForm`. Na pridobljeni komponenti (instanci Multiplierja) je nato poklicana tovarna konkretnega obrazca - kar je anonimna funkcija, ki smo jo Multiplierju v konstruktorju predali.

V naslednji iteraciji foreacha metoda `createComponentShopForm` ne bo več klicana (komponenta obstaja), ker pa iščemo njenega drugega potomca (`$item->id` bo v vsaki iteraciji drugačen), bo ponovno poklicana anonimna funkcija in nam vrnila nov obrazec.

Edino, kar preostane, je zagotoviti, da nam obrazec v košarico doda resnično tisto blago, ki ga mora - trenutno je obrazec pri vsakem blagu popolnoma enak. Pomagala nam bo lastnost Multiplierja (in na splošno vsake tovarne na komponento v Nette Frameworku), in sicer ta, da vsaka tovarna kot svoj prvi argument dobi ime tvořené komponenty. V našem primeru bo to `$item->id`, kar je točno tisti podatek, ki ga potrebujemo. Dovolj je torej rahlo prilagoditi tvorbu obrazca:

```php
protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function ($itemId) {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('count', 'Število kosov:')
			->setRequired();
		$form->addHidden('itemId', $itemId);
		$form->addSubmit('send', 'Dodaj v košarico');
		return $form;
	});
}
```

Multiplier: dinamične komponente

Orodje za dinamično ustvarjanje interaktivnih komponent

Izhajajmo iz tipičnega primera: imejmo seznam blaga v spletni trgovini, pri čemer bomo pri vsakem želeli izpisati obrazec za dodajanje blaga v košarico. Ena od možnih variant je oviti celoten izpis v en obrazec. Veliko udobnejši način pa nam ponuja Nette\Application\UI\Multiplier.

Multiplier omogoča udobno definiranje tovarniške metode za več komponent. Deluje na principu ugnezdenih komponent – vsaka komponenta, ki deduje od Nette\ComponentModel\Container, lahko vsebuje druge komponente.

Glej poglavje o komponentnem modelu v dokumentaciji ali predavanje Honze Tvrdíka.

Bistvo Multiplierja je, da nastopa v vlogi starša, ki si svoje potomce lahko ustvarja dinamično s pomočjo povratnega klica (callback), predanega v konstruktorju. Glej primer:

protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function () {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('count', 'Število kosov:')
			->setRequired();
		$form->addSubmit('send', 'Dodaj v košarico');
		return $form;
	});
}

Zdaj lahko v predlogi enostavno pri vsakem blagu pustimo izrisati obrazec – in vsak bo resnično edinstvena komponenta.

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

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

Argument, predan v znački {control}, je v formatu, ki pravi:

  1. pridobi komponento shopForm
  2. in iz nje pridobi potomca $item->id

Pri prvem klicu točke 1. shopForm še ne obstaja, zato se pokliče njegova tovarna createComponentShopForm. Na pridobljeni komponenti (instanci Multiplierja) je nato poklicana tovarna konkretnega obrazca – kar je anonimna funkcija, ki smo jo Multiplierju v konstruktorju predali.

V naslednji iteraciji foreacha metoda createComponentShopForm ne bo več klicana (komponenta obstaja), ker pa iščemo njenega drugega potomca ($item->id bo v vsaki iteraciji drugačen), bo ponovno poklicana anonimna funkcija in nam vrnila nov obrazec.

Edino, kar preostane, je zagotoviti, da nam obrazec v košarico doda resnično tisto blago, ki ga mora – trenutno je obrazec pri vsakem blagu popolnoma enak. Pomagala nam bo lastnost Multiplierja (in na splošno vsake tovarne na komponento v Nette Frameworku), in sicer ta, da vsaka tovarna kot svoj prvi argument dobi ime tvořené komponenty. V našem primeru bo to $item->id, kar je točno tisti podatek, ki ga potrebujemo. Dovolj je torej rahlo prilagoditi tvorbu obrazca:

protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function ($itemId) {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('count', 'Število kosov:')
			->setRequired();
		$form->addHidden('itemId', $itemId);
		$form->addSubmit('send', 'Dodaj v košarico');
		return $form;
	});
}
OSZAR »