Πολλαπλασιαστής: Δυναμικά Components
Εργαλείο για δυναμική δημιουργία διαδραστικών components
Ας ξεκινήσουμε από ένα τυπικό παράδειγμα: έχουμε μια λίστα προϊόντων σε ένα e-shop, και για καθένα θέλουμε να εμφανίσουμε μια φόρμα για την προσθήκη του προϊόντος στο καλάθι. Μια πιθανή παραλλαγή είναι να περικλείσουμε ολόκληρη τη λίστα σε μια ενιαία φόρμα. Ωστόσο, ένας πολύ πιο βολικός τρόπος μας προσφέρεται από το Nette\Application\UI\Multiplier.
Ο Multiplier επιτρέπει τον βολικό ορισμό ενός μικρού factory για πολλαπλά components. Λειτουργεί με την αρχή των ένθετων components – κάθε component που κληρονομεί από το Nette\ComponentModel\Container μπορεί να περιέχει άλλα components.
Δείτε το κεφάλαιο για το μοντέλο component στην τεκμηρίωση ή την παρουσίαση του Honza Tvrdík.
Η ουσία του Multiplier είναι ότι λειτουργεί ως γονέας που μπορεί να δημιουργήσει δυναμικά τα παιδιά του χρησιμοποιώντας ένα callback που περνιέται στον κατασκευαστή. Δείτε το παράδειγμα:
protected function createComponentShopForm(): Multiplier
{
return new Multiplier(function () {
$form = new Nette\Application\UI\Form;
$form->addInteger('count', 'Πλήθος ειδών:')
->setRequired();
$form->addSubmit('send', 'Προσθήκη στο καλάθι');
return $form;
});
}
Τώρα μπορούμε απλά στο πρότυπο να αφήσουμε να αποδοθεί η φόρμα για κάθε προϊόν – και καθένα θα είναι πραγματικά ένα μοναδικό component.
{foreach $items as $item}
<h2>{$item->title}</h2>
{$item->description}
{control "shopForm-$item->id"}
{/foreach}
Το όρισμα που περνιέται στην ετικέτα {control}
είναι σε μορφή
που λέει:
- πάρε το component
shopForm
- και από αυτό πάρε τον απόγονο
$item->id
Κατά την πρώτη κλήση του σημείου 1. το shopForm
δεν υπάρχει
ακόμα, οπότε καλείται το factory του createComponentShopForm
. Στο ληφθέν component
(παρουσία του Multiplier) καλείται στη συνέχεια το factory της συγκεκριμένης
φόρμας – που είναι η ανώνυμη συνάρτηση που περάσαμε στον Multiplier στον
κατασκευαστή.
Στην επόμενη επανάληψη του foreach, η μέθοδος createComponentShopForm
δεν θα
κληθεί πλέον (το component υπάρχει), αλλά επειδή ψάχνουμε για έναν άλλο
απόγονό του ($item->id
θα είναι διαφορετικό σε κάθε επανάληψη), η
ανώνυμη συνάρτηση θα κληθεί ξανά και θα μας επιστρέψει μια
νέα φόρμα.
Το μόνο που μένει είναι να διασφαλίσουμε ότι η φόρμα προσθέτει στο
καλάθι πραγματικά το προϊόν που πρέπει – αυτή τη στιγμή η φόρμα είναι
εντελώς ίδια για κάθε προϊόν. Η ιδιότητα του Multiplier (και γενικά κάθε factory
component στο Nette Framework) θα μας βοηθήσει, και αυτή είναι ότι κάθε factory
λαμβάνει ως πρώτο του όρισμα το όνομα του component που δημιουργείται. Στην
περίπτωσή μας, αυτό θα είναι το $item->id
, που είναι ακριβώς η
πληροφορία που χρειαζόμαστε. Αρκεί λοιπόν να τροποποιήσουμε ελαφρώς
τη δημιουργία της φόρμας:
protected function createComponentShopForm(): Multiplier
{
return new Multiplier(function ($itemId) {
$form = new Nette\Application\UI\Form;
$form->addInteger('count', 'Πλήθος ειδών:')
->setRequired();
$form->addHidden('itemId', $itemId);
$form->addSubmit('send', 'Προσθήκη στο καλάθι');
return $form;
});
}