Angular 2 bietet @ViewChild
, @ViewChildren
, @ContentChild
und @ContentChildren
Dekorateure für eine Komponente der untergeordneten Elemente abfragt.
Was ist der Unterschied zwischen den ersten beiden und den beiden letzteren?
Angular 2 bietet @ViewChild
, @ViewChildren
, @ContentChild
und @ContentChildren
Dekorateure für eine Komponente der untergeordneten Elemente abfragt.
Was ist der Unterschied zwischen den ersten beiden und den beiden letzteren?
Antworten:
Ich beantworte Ihre Frage mit der Shadow DOM- und Light DOM- Terminologie (sie stammt von Webkomponenten, mehr dazu hier ). Allgemein:
@Component({
selector: 'some-component',
template: `
<h1>I am Shadow DOM!</h1>
<h2>Nice to meet you :)</h2>
<ng-content></ng-content>
`;
})
class SomeComponent { /* ... */ }
@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>
`
})
class AnotherComponent { /* ... */ }
Die Antwort auf Ihre Frage ist also ziemlich einfach:
Der Unterschied zwischen
@ViewChildren
und@ContentChildren
besteht darin, dass@ViewChildren
in Shadow DOM nach Elementen gesucht wird, während@ContentChildren
in Light DOM nach Elementen gesucht wird.
@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 Kind
Wie 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.
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-widget
der Sicht comp-a
ist das ContentChild
und comp-b
ist das ViewChild
. CompomentChildren
und ViewChildren
geben Sie eine iterable zurück, während xChild eine einzelne Instanz zurückgibt.
<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.
<home>
<child>
<small-child><small-child>
</child>
</home>
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.