Quelle bonne question! Je l' aime entendre ce que les autres ont à dire, mais voici les directives que j'utilise.
La prémisse à haute altitude: la portée est utilisée comme la «colle» que nous utilisons pour communiquer entre le contrôleur parent, la directive et le modèle de directive.
Portée parent:, scope: false
donc pas de nouvelle portée du tout
Je n'utilise pas cela très souvent, mais comme l'a dit @MarkRajcok, si la directive n'accède à aucune variable de portée (et évidemment n'en définit aucune!), Cela ne pose aucun problème en ce qui me concerne. Cela est également utile pour les directives enfants qui ne sont utilisées que dans le contexte de la directive parent (bien qu'il y ait toujours des exceptions à cela) et qui n'ont pas de modèle. Fondamentalement, tout ce qui a un modèle n'appartient pas à partager une étendue, car vous exposez intrinsèquement cette étendue pour l'accès et la manipulation (mais je suis sûr qu'il y a des exceptions à cette règle).
À titre d'exemple, j'ai récemment créé une directive qui dessine un graphique vectoriel (statique) à l'aide d'une bibliothèque SVG que je suis en train d'écrire. Il s'agit de $observe
deux attributs ( width
et height
) et les utilise dans ses calculs, mais il ne définit ni ne lit aucune variable de portée et n'a aucun modèle. Il s'agit d'un bon cas d'utilisation pour ne pas créer une autre étendue; nous n'en avons pas besoin, alors pourquoi s'embêter?
Mais dans une autre directive SVG, cependant, j'avais besoin d'un ensemble de données à utiliser et je devais en outre stocker un tout petit peu d'état. Dans ce cas, l'utilisation de la portée parent serait irresponsable (encore une fois, d'une manière générale). Donc au lieu...
Portée enfant: scope: true
Les directives avec une portée enfant sont contextuelles et sont destinées à interagir avec la portée actuelle.
De toute évidence, un avantage clé de cela sur une portée isolée est que l'utilisateur est libre d'utiliser l'interpolation sur tous les attributs qu'il souhaite; Par exemple, l'utilisation class="item-type-{{item.type}}"
d'une directive avec une portée isolée ne fonctionnera pas par défaut, mais fonctionne très bien avec une directive enfant car tout ce qui est interpolé peut toujours être trouvé par défaut dans la portée parent. De plus, la directive elle-même peut évaluer en toute sécurité les attributs et les expressions dans le contexte de sa propre portée sans se soucier de la pollution ou des dommages au parent.
Par exemple, une info-bulle est quelque chose qui vient d'être ajoutée; une portée isolée ne fonctionnerait pas (par défaut, voir ci-dessous) car il est prévu que nous utiliserons ici d'autres directives ou attributs interpolés. L'info-bulle n'est qu'une amélioration. Mais l'info-bulle doit également définir certaines choses sur la portée à utiliser avec une sous-directive et / ou un modèle et évidemment gérer son propre état, il serait donc assez mauvais d'utiliser la portée parent. Nous le polluons ou l'endommagons, et ni l'un ni l'autre n'est bueno.
Je me retrouve à utiliser des portées enfant plus souvent que des portées isolées ou parent.
Isoler la portée: scope: {}
C'est pour les composants réutilisables. :-)
Mais sérieusement, je considère les "composants réutilisables" comme des "composants autonomes". L'intention est qu'elles doivent être utilisées dans un but spécifique, donc les combiner avec d'autres directives ou ajouter d'autres attributs interpolés au nœud DOM n'a pas de sens en soi.
Pour être plus précis, tout ce qui est nécessaire pour cette fonctionnalité autonome est fourni via des attributs spécifiés évalués dans le contexte de la portée parent; ce sont soit des chaînes unidirectionnelles ('@'), des expressions unidirectionnelles ('&'), soit des liaisons de variables bidirectionnelles ('=').
Sur les composants autonomes, il n'est pas logique de devoir lui appliquer d'autres directives ou attributs car il existe par lui-même. Son style est régi par son propre modèle (si nécessaire) et peut contenir le contenu approprié (si nécessaire). Il est autonome, nous l'avons donc mis dans une portée isolée pour dire: "Ne jouez pas avec ça. Je vous donne une API définie à travers ces quelques attributs."
Une bonne pratique consiste à exclure autant de choses basées sur des modèles du lien directif et des fonctions de contrôleur que possible. Cela fournit un autre point de configuration "de type API": l'utilisateur de la directive peut simplement remplacer le modèle! La fonctionnalité est restée la même et son API interne n'a jamais été touchée, mais nous pouvons jouer avec le style et la mise en œuvre DOM autant que nous le devons. ui / bootstrap est un excellent exemple de la façon de bien faire cela parce que Peter & Pawel sont géniaux.
Les portées isolées sont également idéales pour une utilisation avec la transclusion. Prenez des onglets; ils ne sont pas seulement la fonctionnalité tout, mais tout ce qui est à l' intérieur de celui - ci peuvent être évalués librement dans le cadre des parents tout en laissant les pattes (et vitres) pour faire ce qu'ils veulent. Les onglets ont clairement leur propre état , qui appartient à la portée (pour interagir avec le modèle), mais cet état n'a rien à voir avec le contexte dans lequel il a été utilisé - il est entièrement interne à ce qui fait d'une directive tab une directive tab. De plus, cela n'a pas beaucoup de sens d'utiliser d'autres directives avec les onglets. Ce sont des onglets - et nous avons déjà cette fonctionnalité!
Entourez-le de plus de fonctionnalités ou transcluez plus de fonctionnalités, mais la directive est ce qu'elle est déjà.
Cela dit, je dois noter qu'il existe des moyens de contourner certaines des limitations (c'est-à-dire les fonctionnalités) d'une portée isolée, comme l'a suggéré @ProLoser dans sa réponse. Par exemple, dans la section portée enfant, j'ai mentionné l'interpolation sur les attributs non directifs se brisant lors de l'utilisation d'une portée isolée (par défaut). Mais l'utilisateur pourrait, par exemple, simplement utiliser class="item-type-{{$parent.item.type}}"
et cela fonctionnerait à nouveau. Donc, s'il existe une raison impérieuse d'utiliser une étendue isolée sur une étendue enfant mais que vous vous inquiétez de certaines de ces limitations, sachez que vous pouvez les contourner presque toutes si vous en avez besoin.
Résumé
Les directives sans nouvelle portée sont en lecture seule; ils sont totalement fiables (c'est-à-dire internes à l'application) et ils ne touchent pas à la prise. Les directives avec une portée enfant ajoutent des fonctionnalités, mais ce ne sont pas les seules fonctionnalités. Enfin, les étendues d'isolement sont destinées aux directives qui sont le but entier; ils sont autonomes, il est donc correct (et le plus "correct") de les laisser devenir voyous.
Je voulais faire part de mes premières réflexions, mais en pensant à plus de choses, je mettrai à jour cela. Mais merde - c'est long pour une réponse SO ...
PS: Totalement tangentiel, mais comme nous parlons de portées, je préfère dire "prototypique" alors que d'autres préfèrent "prototypique", qui semble être plus précis mais qui ne déroule pas du tout bien de la langue. :-)