Πολλαπλασιαστής: Δυναμικά 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} είναι σε μορφή που λέει:

  1. πάρε το component shopForm
  2. και από αυτό πάρε τον απόγονο $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;
	});
}
έκδοση: 4.0