Modèle de composant
Un concept important dans Nette est le composant. Nous insérons des composants interactifs visuels dans les pages, les formulaires ou tous
leurs éléments sont également des composants. Il existe deux classes de base dont héritent tous ces composants, elles font
partie du paquetage nette/component-model
et sont responsables de la création de la hiérarchie de l'arbre des
composants.
Component
Nette\ComponentModel\Component
est l'ancêtre commun de tous les composants. Il contient la méthode getName()
qui renvoie le nom du composant et la
méthode getParent()
qui renvoie son parent. Les deux peuvent être définis avec la méthode
setParent()
– le premier paramètre est le parent et le second est le nom du composant.
lookup (string $type): ?Component
Recherche dans la hiérarchie un objet de la classe ou de l'interface souhaitée. Par exemple,
$component->lookup(Nette\Application\UI\Presenter::class)
renvoie présentateur si le composant est relié à
celui-ci, malgré plusieurs niveaux.
lookupPath (string $type): ?string
Renvoie ce que l'on appelle le chemin, qui est une chaîne formée par la concaténation des noms de tous les composants sur le
chemin entre le composant actuel et le composant recherché. Ainsi, par exemple,
$component->lookupPath(Nette\Application\UI\Presenter::class)
renvoie l'identifiant unique du composant par
rapport au présentateur.
Container
Nette\ComponentModel\Container
est le composant parent, c'est-à-dire le composant contenant les enfants et formant ainsi l'arborescence. Il dispose de méthodes
pour ajouter, récupérer et supprimer facilement des composants. Il est l'ancêtre, par exemple, du formulaire ou des classes
Control
et Presenter
.
getComponent (string $name): ?Component
Renvoie un composant. La tentative d'appeler un enfant non défini entraîne l'invocation de la fabrique createComponent($name).
La méthode createComponent($name)
invoque la méthode createComponent<component name>
dans le
composant courant et passe le nom du composant comme paramètre. Le composant créé est ensuite transmis au composant courant en
tant que son enfant. Nous appelons ces usines de composants, elles peuvent être implémentées dans des classes héritées de
Container
.
getComponents(): array
Renvoie les descendants directs sous la forme d'un tableau. Les clés contiennent les noms de ces composants. Note : dans la version 3.0.x, la méthode renvoyait un itérateur au lieu d'un tableau, et son premier paramètre spécifiait s'il fallait itérer à travers les composants en profondeur, et le second représentait un filtre de type. Ces paramètres sont obsolètes.
getComponentTree(): array
Renvoie toute la hiérarchie des composants, y compris tous les composants enfants imbriqués, sous la forme d'un tableau indexé. La recherche se fait d'abord en profondeur.
Surveillance des ancêtres
Le modèle de composant Nette permet un travail très dynamique sur l'arbre (nous pouvons supprimer, déplacer, ajouter des composants), ce serait donc une erreur de se fier au fait qu'après avoir créé un composant, le parent, le parent du parent, etc. sont connus immédiatement (dans le constructeur). En général, le parent n'est pas connu du tout lorsque le composant est créé.
Comment savoir quand un composant a été ajouté à l'arbre du présentateur ? Suivre le changement de parent n'est pas
suffisant, car le parent du parent pourrait avoir été attaché au présentateur, par exemple. La méthode monitor($type, $attached,
$detached) peut vous aider. Chaque composant peut surveiller un nombre quelconque de classes et d'interfaces. La connexion ou
la déconnexion est annoncée en appelant les callbacks $attached
et $detached
, respectivement, et en
passant l'objet de la classe surveillée.
Un exemple : La classe UploadControl
, représentant l'élément de formulaire pour le téléchargement de fichiers
dans Nette Forms, doit définir l'attribut du formulaire enctype
à la valeur multipart/form-data
. Mais
au moment de la création de l'objet, elle ne doit être attachée à aucun formulaire. Quand modifier le formulaire ? La solution
est simple – nous créons une demande de surveillance dans le constructeur :
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');
});
// ...
}
// ...
}
et lorsque le formulaire est disponible, le callback est appelé. (Auparavant, les méthodes communes attached
et
detached
étaient utilisées à la place).