Μοντέλο Component

Ένας σημαντικός όρος στο Nette είναι το component. Στις σελίδες εισάγουμε οπτικά διαδραστικά components, τα components είναι επίσης φόρμες ή όλα τα στοιχεία τους. Οι δύο βασικές κλάσεις από τις οποίες κληρονομούν όλα αυτά τα components αποτελούν μέρος του πακέτου nette/component-model και έχουν ως αποστολή τη δημιουργία μιας ιεραρχικής δενδροειδούς δομής components.

Component

Η Nette\ComponentModel\Component είναι ο κοινός πρόγονος όλων των components. Περιέχει τις μεθόδους getName() που επιστρέφει το όνομα του component και τη μέθοδο getParent() που επιστρέφει τον γονέα του. Και τα δύο μπορούν να οριστούν με τη μέθοδο setParent() – η πρώτη παράμετρος είναι ο γονέας και η δεύτερη το όνομα του component.

lookup (string $type): ?Component

Αναζητά στην ιεραρχία προς τα πάνω ένα αντικείμενο της ζητούμενης κλάσης ή interface. Για παράδειγμα, το $component->lookup(Nette\Application\UI\Presenter::class) επιστρέφει τον presenter, εάν το component είναι συνδεδεμένο με αυτόν, ακόμη και μέσω πολλών επιπέδων.

lookupPath (string $type): ?string

Επιστρέφει τη λεγόμενη διαδρομή, η οποία είναι μια συμβολοσειρά που δημιουργείται από τη συνένωση των ονομάτων όλων των components στη διαδρομή μεταξύ του τρέχοντος και του αναζητούμενου component. Έτσι, π.χ., το $component->lookupPath(Nette\Application\UI\Presenter::class) επιστρέφει ένα μοναδικό αναγνωριστικό του component σε σχέση με τον presenter.

Container

Η Nette\ComponentModel\Container είναι το γονικό component, δηλ. ένα component που περιέχει απογόνους και σχηματίζει έτσι μια δενδροειδή δομή. Διαθέτει μεθόδους για εύκολη προσθήκη, ανάκτηση και αφαίρεση αντικειμένων. Είναι ο πρόγονος, για παράδειγμα, της φόρμας ή των κλάσεων Control και Presenter.

getComponent (string $name): ?Component

Επιστρέφει το component. Κατά την προσπάθεια ανάκτησης ενός μη ορισμένου απογόνου, καλείται το factory createComponent($name). Η μέθοδος createComponent($name) καλεί στο τρέχον component τη μέθοδο createComponent<όνομα_component> και της περνά ως παράμετρο το όνομα του component. Το δημιουργημένο component προστίθεται στη συνέχεια στο τρέχον component ως απόγονός του. Αυτές οι μέθοδοι ονομάζονται factories component και μπορούν να υλοποιηθούν από απογόνους της κλάσης Container.

getComponents(): array

Επιστρέφει τους άμεσους απογόνους ως πίνακα. Τα κλειδιά περιέχουν τα ονόματα αυτών των components. Σημείωση: στην έκδοση 3.0.x η μέθοδος επέστρεφε έναν iterator αντί για πίνακα και η πρώτη της παράμετρος καθόριζε αν τα components έπρεπε να διασχιστούν σε βάθος, και η δεύτερη αντιπροσώπευε ένα φίλτρο τύπου. Αυτές οι παράμετροι είναι deprecated.

getComponentTree(): array

Ανακτά ολόκληρη την ιεραρχία των components, συμπεριλαμβανομένων όλων των ενσωματωμένων θυγατρικών components, ως ευρετηριασμένο πίνακα. Η αναζήτηση γίνεται πρώτα σε βάθος.

Παρακολούθηση προγόνων

Το μοντέλο component του Nette επιτρέπει πολύ δυναμική εργασία με το δέντρο (μπορούμε να αφαιρούμε, να μετακινούμε, να προσθέτουμε components), επομένως θα ήταν λάθος να βασιζόμαστε στο γεγονός ότι μετά τη δημιουργία ενός component είναι αμέσως γνωστός ο γονέας, ο γονέας του γονέα κ.λπ. (στον κατασκευαστή). Τις περισσότερες φορές, ο γονέας δεν είναι καθόλου γνωστός κατά τη δημιουργία.

Πώς να αναγνωρίσετε πότε ένα component συνδέθηκε στο δέντρο του presenter; Η παρακολούθηση της αλλαγής του γονέα δεν αρκεί, γιατί μπορεί να έχει συνδεθεί στον presenter ο γονέας του γονέα, για παράδειγμα. Η μέθοδος monitor($type, $attached, $detached) βοηθάει. Κάθε component μπορεί να παρακολουθεί οποιονδήποτε αριθμό κλάσεων και interfaces. Η σύνδεση ή η αποσύνδεση ανακοινώνεται με την κλήση του callback $attached ή $detached αντίστοιχα, και την παράδοση του αντικειμένου της παρακολουθούμενης κλάσης.

Για καλύτερη κατανόηση, ένα παράδειγμα: η κλάση UploadControl, που αντιπροσωπεύει ένα στοιχείο φόρμας για την αποστολή αρχείων στο Nette Forms, πρέπει να ορίσει το attribute enctype της φόρμας στην τιμή multipart/form-data. Κατά τη στιγμή της δημιουργίας του αντικειμένου, όμως, μπορεί να μην είναι συνδεδεμένο με καμία φόρμα. Πότε λοιπόν πρέπει να τροποποιηθεί η φόρμα; Η λύση είναι απλή – στον κατασκευαστή ζητείται η παρακολούθηση:

class UploadControl extends Nette\Forms\Controls\BaseControl
{
	public function __construct($label)
	{
		$this->monitor(Nette\Forms\Form::class, function ($form): void {
			$form->setHtmlAttribute('enctype', 'multipart/form-data');
		});
		// ...
	}

	// ...
}

και μόλις η φόρμα είναι διαθέσιμη, καλείται το callback. (Παλαιότερα, χρησιμοποιούνταν αντί αυτού η κοινή μέθοδος attached ή detached).

έκδοση: 3.x