Μοντέλο συστατικών
Μια σημαντική έννοια στη Nette είναι το συστατικό. Εισάγουμε οπτικά διαδραστικά στοιχεία σε σελίδες,
φόρμες ή όλα τα στοιχεία τους είναι επίσης στοιχεία. Υπάρχουν δύο
βασικές κλάσεις από τις οποίες κληρονομούν όλα αυτά τα συστατικά,
αποτελούν μέρος του πακέτου nette/component-model
και είναι υπεύθυνες για
τη δημιουργία της ιεραρχίας του δέντρου των συστατικών.
Συστατικό
Nette\ComponentModel\Component
είναι ο κοινός πρόγονος όλων των συστατικών. Περιέχει τη μέθοδο
getName()
που επιστρέφει το όνομα του συστατικού και τη μέθοδο
getParent()
που επιστρέφει τον γονέα του. Και τα δύο μπορούν να
οριστούν με τη μέθοδο setParent()
– η πρώτη παράμετρος είναι ο
γονέας και η δεύτερη το όνομα του συστατικού.
lookup(string $type): ?Component
Αναζητά στην ιεραρχία ένα αντικείμενο της επιθυμητής κλάσης ή
διεπαφής. Για παράδειγμα, το $component->lookup(Nette\Application\UI\Presenter::class)
επιστρέφει το presenter αν το συστατικό είναι συνδεδεμένο με αυτό, παρά τα
πολλά επίπεδα.
lookupPath(string $type): ?string
Επιστρέφει τη λεγόμενη διαδρομή, η οποία είναι μια συμβολοσειρά που
σχηματίζεται από τη συνένωση των ονομάτων όλων των στοιχείων στη
διαδρομή μεταξύ του τρέχοντος στοιχείου και του στοιχείου που
αναζητείται. Έτσι, για παράδειγμα, το
$component->lookupPath(Nette\Application\UI\Presenter::class)
επιστρέφει το μοναδικό
αναγνωριστικό του συστατικού σε σχέση με τον παρουσιαστή.
Δοχείο
Nette\ComponentModel\Container
είναι το γονικό συστατικό, δηλαδή το συστατικό που περιέχει τα παιδιά
και έτσι σχηματίζει τη δενδρική δομή. Διαθέτει μεθόδους για την εύκολη
προσθήκη, ανάκτηση και αφαίρεση στοιχείων. Είναι ο πρόγονος, για
παράδειγμα, της φόρμας ή των κλάσεων Control
και Presenter
.
getComponent(string $name): ?Component
Επιστρέφει ένα συστατικό. Η απόπειρα κλήσης απροσδιόριστου παιδιού
προκαλεί κλήση του εργοστασίου createComponent($name).
Η μέθοδος createComponent($name)
καλεί τη μέθοδο
createComponent<component name>
στο τρέχον συστατικό και περνά το όνομα του
συστατικού ως παράμετρο. Το συστατικό που δημιουργήθηκε περνάει στη
συνέχεια στο τρέχον συστατικό ως παιδί του. Ονομάζουμε αυτά τα
εργοστάσια συστατικών, μπορούν να υλοποιηθούν σε κλάσεις που
κληρονομούνται από το Container
.
getComponents(): array
Επιστρέφει τους άμεσους απογόνους ως πίνακα. Τα κλειδιά περιέχουν τα ονόματα αυτών των στοιχείων. Σημείωση: στην έκδοση 3.0.x, η μέθοδος επέστρεφε έναν επαναλήπτη αντί για έναν πίνακα, και η πρώτη παράμετρος όριζε αν θα επαναλαμβάνονταν τα συστατικά σε βάθος και η δεύτερη αντιπροσώπευε ένα φίλτρο τύπου. Αυτές οι παράμετροι έχουν καταργηθεί.
getComponentTree(): array
Επιστρέφει ολόκληρη την ιεραρχία των στοιχείων, συμπεριλαμβανομένων όλων των φωλιασμένων θυγατρικών στοιχείων ως πίνακα με ευρετήριο. Η αναζήτηση γίνεται πρώτα σε βάθος.
Παρακολούθηση των προγόνων
Το μοντέλο συστατικών της Nette επιτρέπει πολύ δυναμική εργασία στο δέντρο (μπορούμε να αφαιρούμε, να μετακινούμε, να προσθέτουμε συστατικά), οπότε θα ήταν λάθος να βασιστούμε στο γεγονός ότι μετά τη δημιουργία ενός συστατικού, ο γονέας, ο γονέας του γονέα κ.λπ. είναι αμέσως γνωστά (στον κατασκευαστή). Συνήθως ο γονέας δεν είναι καθόλου γνωστός όταν δημιουργείται το συστατικό.
Πώς μπορείτε να μάθετε πότε ένα συστατικό έχει προστεθεί στο δέντρο
του παρουσιαστή; Η παρακολούθηση της αλλαγής του γονέα δεν είναι
αρκετή, επειδή ο γονέας του γονέα θα μπορούσε να έχει προσαρτηθεί στον
παρουσιαστή, για παράδειγμα. Η μέθοδος monitor($type, $attached,
$detached) μπορεί να βοηθήσει. Κάθε στοιχείο μπορεί να παρακολουθεί
οποιονδήποτε αριθμό κλάσεων και διεπαφών. Η σύνδεση ή η αποσύνδεση
ανακοινώνεται με την κλήση των callbacks $attached
και $detached
,
αντίστοιχα, και περνώντας το αντικείμενο της παρακολουθούμενης
κλάσης.
Ένα παράδειγμα: Η κλάση UploadControl
, που αντιπροσωπεύει το
στοιχείο φόρμας για το ανέβασμα αρχείων στη Nette Forms, πρέπει να θέσει το
χαρακτηριστικό 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
).