Multiplier: dynamische Komponenten
Werkzeug zur dynamischen Erstellung interaktiver Komponenten
Beginnen wir mit einem typischen Beispiel: Wir haben eine Liste von Waren in einem E-Shop, und für jede Ware möchten wir ein Formular zum Hinzufügen in den Warenkorb anzeigen. Eine mögliche Variante ist, die gesamte Auflistung in ein einziges Formular zu packen. Einen viel bequemeren Weg bietet uns jedoch Nette\Application\UI\Multiplier.
Multiplier ermöglicht es, bequem eine Factory für mehrere Komponenten zu definieren. Es funktioniert nach dem Prinzip verschachtelter Komponenten – jede Komponente, die von Nette\ComponentModel\Container erbt, kann weitere Komponenten enthalten.
Siehe das Kapitel über das Komponentenmodell in der Dokumentation oder den Vortrag von Honza Tvrdík.
Das Wesen des Multipliers ist, dass er als Elternteil fungiert, der seine Nachkommen dynamisch mithilfe eines im Konstruktor übergebenen Callbacks erstellen kann. Siehe Beispiel:
Jetzt können wir im Template einfach für jeden Artikel das Formular rendern lassen – und jedes wird tatsächlich eine eindeutige Komponente sein.
Das im Tag {control}
übergebene Argument hat ein Format, das besagt:
- hole die Komponente
shopForm
- und hole daraus den Nachkommen
$item->id
Beim ersten Aufruf von Punkt 1. existiert shopForm
noch nicht, also wird seine Factory
createComponentShopForm
aufgerufen. Auf der erhaltenen Komponente (Instanz des Multipliers) wird dann die Factory des
konkreten Formulars aufgerufen – was die anonyme Funktion ist, die wir dem Multiplier im Konstruktor übergeben haben.
In der nächsten Iteration des Foreach wird die Methode createComponentShopForm
nicht mehr aufgerufen (die
Komponente existiert), aber da wir einen anderen Nachkommen suchen ($item->id
wird in jeder Iteration anders
sein), wird die anonyme Funktion erneut aufgerufen und gibt uns ein neues Formular zurück.
Das Einzige, was übrig bleibt, ist sicherzustellen, dass das Formular tatsächlich die richtige Ware in den Warenkorb
legt – derzeit ist das Formular für jeden Artikel völlig identisch. Hier hilft uns eine Eigenschaft des Multipliers (und
generell jeder Komponenten-Factory im Nette Framework), nämlich dass jede Factory als erstes Argument den Namen der zu
erstellenden Komponente erhält. In unserem Fall ist das $item->id
, was genau die Information ist, die wir
benötigen. Es genügt also, die Erstellung des Formulars leicht anzupassen: