Multiplikator: Dinamične komponente
Orodje za dinamično ustvarjanje interaktivnih komponent
Začnimo s tipičnim problemom: imamo seznam izdelkov na spletni strani e-trgovine in vsak izdelek želimo opremiti z obrazcem Dodaj v košarico. Eden od načinov je, da celoten seznam zapakiramo v en sam obrazec. Priročnejši način je uporaba Nette\Application\UI\Multiplier.
Funkcija Multiplier vam omogoča, da določite tovarno za več sestavnih delov. Temelji na načelu vgnezdenih komponent – vsaka komponenta, ki podeduje od Nette\ComponentModel\Container, lahko vsebuje druge komponente.
Oglejte si model komponent v dokumentaciji.
Multiplier nastopa kot starševska komponenta, ki lahko dinamično ustvari svoje otroke z uporabo povratnega klica, posredovanega v konstruktorju. Oglejte si primer:
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;
});
}
V predlogi lahko prikažemo obrazec za vsak izdelek – in vsak obrazec bo dejansko edinstvena komponenta.
{foreach $items as $item}
<h2>{$item->title}</h2>
{$item->description}
{control "shopForm-$item->id"}
{/foreach}
Argument, posredovan oznaki {control}
, pravi:
- pridobi komponento
shopForm
- in vrni njenega otroka
$item->id
Med prvim klicem 1. komponenta shopForm
še ne obstaja, zato se za njeno ustvarjanje pokliče metoda
createComponentShopForm
. Nato se pokliče anonimna funkcija, ki je Multiplierju posredovana kot parameter, in ustvari
se obrazec.
V naslednjih iteracijah foreach
se metoda createComponentShopForm
ne kliče več, ker komponenta že
obstaja. Ker pa se sklicujemo na drugega otroka ($item->id
se med iteracijami spreminja), se ponovno pokliče
anonimna funkcija in ustvari se nov obrazec.
Zadnja stvar je zagotoviti, da obrazec dejansko doda pravi izdelek v košarico, saj so v trenutnem stanju vsi obrazci enaki
in ne moremo razlikovati, katerim izdelkom pripadajo. Za to lahko uporabimo lastnost Multiplierja (in na splošno vsake metode
tovarne komponent v Nette Framework), da vsaka metoda tovarne komponent kot prvi argument prejme ime ustvarjene komponente.
V našem primeru je to $item->id
, kar je natanko tisto, kar potrebujemo za razlikovanje posameznih izdelkov. Vse,
kar morate storiti, je, da spremenite kodo za ustvarjanje obrazca:
protected function createComponentShopForm(): Multiplier
{
return new Multiplier(function ($itemId) {
$form = new Nette\Application\UI\Form;
$form->addInteger('amount', 'Amount:')
->setRequired();
$form->addHidden('itemId', $itemId);
$form->addSubmit('send', 'Add to cart');
return $form;
});
}