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).

version: 3.x