Je répondrai à votre question en utilisant la terminologie Shadow DOM et Light DOM (elle provient de composants Web, voir plus ici ). En général:
Shadow DOM - est un DOM interne de votre composant qui est défini par vous (en tant que créateur du composant ) et caché à un utilisateur final. Par exemple:
@Component({
selector:'some-component',
template:`<h1>I am Shadow DOM!</h1><h2>Nice to meet you :)</h2><ng-content></ng-content>`;})classSomeComponent{/* ... */}
Light DOM - est un DOM qu'un utilisateur final de votre composant fournit à votre composant. Par exemple:
@Component({
selector:'another-component',
directives:[SomeComponent],
template:`<some-component><h1>Hi! I am Light DOM!</h1><h2>So happy to see you!</h2></some-component>`})classAnotherComponent{/* ... */}
Donc, la réponse à votre question est assez simple:
La différence entre @ViewChildrenet @ContentChildrenest que @ViewChildrenrechercher des éléments dans Shadow DOM et les @ContentChildrenrechercher dans Light DOM.
L'entrée de blog blog.mgechev.com/2016/01/23/… de Minko Gechew a plus de sens pour moi. @ContentChildren sont les enfants, insérés par projection de contenu (les enfants entre <ng-content> </ng-content>). Du blog Minkos: "D'autre part, ** les éléments qui sont utilisés entre les balises d'ouverture et de fermeture de l'élément hôte d'un composant donné sont appelés * enfants de contenu **." Shadow DOM et l'encapsulation de vue dans Angular2 sont décrits ici: blog.bientram.io/angular/2015/06/29/… .
westor
4
Pour moi, il semble que @TemplateChildren(au lieu de @ViewChildren) ou @HostChildren(au lieu de @ContentChildren) auraient été de bien meilleurs noms, car dans un tel contexte, tout ce dont nous parlons est lié à la vue, et la liaison wrt est également liée au contenu.
superjos
35
@ViewChildren== votre propre enfant; @ContentChildren== enfant de quelqu'un d'autre
candidJ
107
Comme son nom l'indique, @ContentChildet les @ContentChildrenrequêtes renverront les directives existant à l'intérieur de l' <ng-content></ng-content>élément de votre vue, tandis que @ViewChildet @ViewChildrenne regarderont que les éléments qui se trouvent directement sur votre modèle de vue.
Utilisez donc @ViewChild (ren) à moins que vous n'ayez des composants dans votre vue, auquel cas revenez à @ContentChild (ren)?
Ben Taliadoros
31
Cette vidéo d'Angular Connect contient d'excellentes informations sur ViewChildren, ViewChild, ContentChildren et ContentChild
https://youtu.be/4YmnbGoh49U
@Component({
template: `
<my-widget>
<comp-a/>
</my-widget>
`
})
class App {}
@Component({
selector: 'my-widget',
template: `<comp-b/>`
})
class MyWidget {}
Du my-widgetpoint de vue de, comp-aest le ContentChildet comp-best le ViewChild. CompomentChildrenet ViewChildrenrenvoie un itérable tandis que le xChild renvoie une seule instance.
Vous pouvez maintenant saisir tous les éléments enfants dans le contexte du composant home avec @viewChildren car ils sont directement ajoutés dans le modèle du composant home. Mais, lorsque vous essayez d'accéder à l' <small-child>élément à partir du contexte du composant enfant, vous ne pouvez pas y accéder car il n'est pas directement ajouté dans le modèle de composant enfant. Il est ajouté par projection de contenu dans le composant enfant par composant home. C'est là qu'intervient @contentChild et vous pouvez le récupérer avec @contentChild.
La différence se produit lorsque vous essayez d'accéder à la référence des éléments dans le contrôleur. Vous pouvez accéder à tous les éléments qui sont directement ajoutés au modèle de composant par @viewChild. Mais vous ne pouvez pas saisir la référence des éléments projetés avec @viewChild Pour accéder à l'élément projeté, vous devez utiliser @contentChild.
Réponses:
Je répondrai à votre question en utilisant la terminologie Shadow DOM et Light DOM (elle provient de composants Web, voir plus ici ). En général:
Donc, la réponse à votre question est assez simple:
la source
@TemplateChildren
(au lieu de@ViewChildren
) ou@HostChildren
(au lieu de@ContentChildren
) auraient été de bien meilleurs noms, car dans un tel contexte, tout ce dont nous parlons est lié à la vue, et la liaison wrt est également liée au contenu.@ViewChildren
== votre propre enfant;@ContentChildren
== enfant de quelqu'un d'autreComme son nom l'indique,
@ContentChild
et les@ContentChildren
requêtes renverront les directives existant à l'intérieur de l'<ng-content></ng-content>
élément de votre vue, tandis que@ViewChild
et@ViewChildren
ne regarderont que les éléments qui se trouvent directement sur votre modèle de vue.la source
Cette vidéo d'Angular Connect contient d'excellentes informations sur ViewChildren, ViewChild, ContentChildren et ContentChild https://youtu.be/4YmnbGoh49U
Du
my-widget
point de vue de,comp-a
est leContentChild
etcomp-b
est leViewChild
.CompomentChildren
etViewChildren
renvoie un itérable tandis que le xChild renvoie une seule instance.la source
<comp-b><ng-content></ng-content></comp-b>
correct?Prenons un exemple, nous avons un composant home et un composant enfant et à l'intérieur du composant enfant un petit composant enfant.
Vous pouvez maintenant saisir tous les éléments enfants dans le contexte du composant home avec @viewChildren car ils sont directement ajoutés dans le modèle du composant home. Mais, lorsque vous essayez d'accéder à l'
<small-child>
élément à partir du contexte du composant enfant, vous ne pouvez pas y accéder car il n'est pas directement ajouté dans le modèle de composant enfant. Il est ajouté par projection de contenu dans le composant enfant par composant home. C'est là qu'intervient @contentChild et vous pouvez le récupérer avec @contentChild.La différence se produit lorsque vous essayez d'accéder à la référence des éléments dans le contrôleur. Vous pouvez accéder à tous les éléments qui sont directement ajoutés au modèle de composant par @viewChild. Mais vous ne pouvez pas saisir la référence des éléments projetés avec @viewChild Pour accéder à l'élément projeté, vous devez utiliser @contentChild.
la source