Ich beantworte Ihre Frage mit der Shadow DOM- und Light DOM- Terminologie (sie stammt von Webkomponenten, mehr dazu hier ). Allgemein:
Schatten-DOM - ist ein internes DOM Ihrer Komponente, das von Ihnen (als Ersteller der Komponente ) definiert und vor einem Endbenutzer verborgen wird. Beispielsweise:
@Component({
selector:'some-component',
template:`<h1>I am Shadow DOM!</h1><h2>Nice to meet you :)</h2><ng-content></ng-content>`;})classSomeComponent{/* ... */}
Light DOM - ist ein DOM, das ein Endbenutzer Ihrer Komponente in Ihre Komponente einspeist. Beispielsweise:
@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{/* ... */}
Die Antwort auf Ihre Frage ist also ziemlich einfach:
Der Unterschied zwischen @ViewChildrenund @ContentChildrenbesteht darin, dass @ViewChildrenin Shadow DOM nach Elementen gesucht wird, während @ContentChildrenin Light DOM nach Elementen gesucht wird.
Der Blogeintrag blog.mgechev.com/2016/01/23/… von Minko Gechew macht für mich mehr Sinn. @ContentChildren sind die untergeordneten Elemente, die durch Inhaltsprojektion eingefügt werden (die untergeordneten Elemente zwischen <ng-content> </ ng-content>). Aus dem Minkos-Blog: "Andererseits werden ** Elemente, die zwischen den öffnenden und schließenden Tags des Host-Elements einer bestimmten Komponente verwendet werden, als * untergeordnete Elemente ** bezeichnet." Das Shadow DOM und die Ansichtskapselung in Angular2 werden hier beschrieben: blog.ilsttram.io/angular/2015/06/29/… .
Westor
4
Für mich klingt es so , als wären @TemplateChildren(anstelle von @ViewChildren) oder @HostChildren(anstelle von @ContentChildren) viel bessere Namen gewesen, da in einem solchen Kontext alles, worüber wir sprechen, auf die Ansicht bezogen ist und die Wrt-Bindung auch auf den Inhalt.
Superjos
34
@ViewChildren== dein eigenes Kind; @ContentChildren== jemand anderes Kind
CandidJ
105
Wie der Name schon sagt, @ContentChildund @ContentChildrenAbfragen werden Richtlinien zurückkehren innerhalb des bestehenden <ng-content></ng-content>Elements Ihrer Ansicht, während @ViewChildund @ViewChildrennur auf Elemente suchen , die direkt auf Ihrer Ansicht Vorlage sind.
Verwenden Sie also @ViewChild (ren), es sei denn, Sie haben Komponenten in Ihrer Ansicht. In diesem Fall greifen Sie auf @ContentChild (ren) zurück.
Ben Taliadoros
31
Dieses Video von Angular Connect enthält hervorragende Informationen zu ViewChildren, ViewChild, ContentChildren und ContentChild
https://youtu.be/4YmnbGoh49U
@Component({
template: `
<my-widget>
<comp-a/>
</my-widget>
`
})
class App {}
@Component({
selector: 'my-widget',
template: `<comp-b/>`
})
class MyWidget {}
Aus my-widgetder Sicht comp-aist das ContentChildund comp-bist das ViewChild. CompomentChildrenund ViewChildrengeben Sie eine iterable zurück, während xChild eine einzelne Instanz zurückgibt.
Sie haben ein klares und einfaches Beispiel gemacht, aber die Vorlage von MyWidget sollte <comp-b><ng-content></ng-content></comp-b>richtig sein?
Arjel vor
1
Nehmen wir ein Beispiel: Wir haben eine Home-Komponente und eine untergeordnete Komponente und innerhalb der untergeordneten Komponente eine kleine untergeordnete Komponente.
Jetzt können Sie mit @viewChildren alle untergeordneten Elemente im Kontext der Home-Komponente abrufen, da diese direkt in der Vorlage der Home-Komponente hinzugefügt werden. Wenn Sie jedoch versuchen, <small-child>über den Kontext der untergeordneten Komponente auf ein Element zuzugreifen , können Sie nicht darauf zugreifen, da es nicht direkt in der Vorlage für die untergeordnete Komponente hinzugefügt wird. Es wird durch Inhaltsprojektion in die untergeordnete Komponente von der Home-Komponente hinzugefügt. Hier kommt @contentChild ins Spiel und Sie können es mit @contentChild abrufen.
Der Unterschied tritt auf, wenn Sie versuchen, auf die Elementreferenz im Controller zuzugreifen. Sie können auf Grab greifen, um alle Elemente zu erfassen, die von @viewChild direkt zur Vorlage der Komponente hinzugefügt werden. Mit @viewChild können Sie jedoch keine Referenz für projizierte Elemente abrufen. Um auf projizierte Elemente zugreifen zu können, müssen Sie @contentChild verwenden.
Antworten:
Ich beantworte Ihre Frage mit der Shadow DOM- und Light DOM- Terminologie (sie stammt von Webkomponenten, mehr dazu hier ). Allgemein:
Die Antwort auf Ihre Frage ist also ziemlich einfach:
quelle
@TemplateChildren
(anstelle von@ViewChildren
) oder@HostChildren
(anstelle von@ContentChildren
) viel bessere Namen gewesen, da in einem solchen Kontext alles, worüber wir sprechen, auf die Ansicht bezogen ist und die Wrt-Bindung auch auf den Inhalt.@ViewChildren
== dein eigenes Kind;@ContentChildren
== jemand anderes KindWie der Name schon sagt,
@ContentChild
und@ContentChildren
Abfragen werden Richtlinien zurückkehren innerhalb des bestehenden<ng-content></ng-content>
Elements Ihrer Ansicht, während@ViewChild
und@ViewChildren
nur auf Elemente suchen , die direkt auf Ihrer Ansicht Vorlage sind.quelle
Dieses Video von Angular Connect enthält hervorragende Informationen zu ViewChildren, ViewChild, ContentChildren und ContentChild https://youtu.be/4YmnbGoh49U
Aus
my-widget
der Sichtcomp-a
ist dasContentChild
undcomp-b
ist dasViewChild
.CompomentChildren
undViewChildren
geben Sie eine iterable zurück, während xChild eine einzelne Instanz zurückgibt.quelle
<comp-b><ng-content></ng-content></comp-b>
richtig sein?Nehmen wir ein Beispiel: Wir haben eine Home-Komponente und eine untergeordnete Komponente und innerhalb der untergeordneten Komponente eine kleine untergeordnete Komponente.
Jetzt können Sie mit @viewChildren alle untergeordneten Elemente im Kontext der Home-Komponente abrufen, da diese direkt in der Vorlage der Home-Komponente hinzugefügt werden. Wenn Sie jedoch versuchen,
<small-child>
über den Kontext der untergeordneten Komponente auf ein Element zuzugreifen , können Sie nicht darauf zugreifen, da es nicht direkt in der Vorlage für die untergeordnete Komponente hinzugefügt wird. Es wird durch Inhaltsprojektion in die untergeordnete Komponente von der Home-Komponente hinzugefügt. Hier kommt @contentChild ins Spiel und Sie können es mit @contentChild abrufen.Der Unterschied tritt auf, wenn Sie versuchen, auf die Elementreferenz im Controller zuzugreifen. Sie können auf Grab greifen, um alle Elemente zu erfassen, die von @viewChild direkt zur Vorlage der Komponente hinzugefügt werden. Mit @viewChild können Sie jedoch keine Referenz für projizierte Elemente abrufen. Um auf projizierte Elemente zugreifen zu können, müssen Sie @contentChild verwenden.
quelle