Odpowiem na twoje pytanie za pomocą terminologii Shadow DOM i Light DOM (pochodzi ona z komponentów internetowych, więcej informacji tutaj ). Ogólnie:
Shadow DOM - to wewnętrzny DOM twojego komponentu, który jest zdefiniowany przez ciebie (jako twórcę komponentu ) i ukryty przed użytkownikiem końcowym. Na przykład:
@Component({
selector:'some-component',
template:`<h1>I am Shadow DOM!</h1><h2>Nice to meet you :)</h2><ng-content></ng-content>`;})classSomeComponent{/* ... */}
Lekki DOM - to DOM, który użytkownik końcowy twojego komponentu dostarcza do swojego komponentu. Na przykład:
@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{/* ... */}
Tak więc odpowiedź na twoje pytanie jest dość prosta:
Różnica między @ViewChildreni @ContentChildrenpolega na tym, że @ViewChildrenszukają elementów w Shadow DOM, a @ContentChildrenszukają ich w Light DOM.
Wpis na blogu blog.mgechev.com/2016/01/23/... od Minko Gechew ma dla mnie większy sens. @ContentChildren to dzieci, wstawiane przez projekcję treści (dzieci między <ng-content> </ng-content>). Z blogu Minkos: „Z drugiej strony ** elementy, które są używane między otwierającymi i zamykającymi znacznikami elementu hosta danego komponentu, nazywane są * elementami potomnymi **.” Shadow DOM i enkapsulacja widoku w Angular2 są opisane tutaj: blog.thoughtram.io/angular/2015/06/29/… .
zachodni
4
Dla mnie to brzmi jak @TemplateChildren(zamiast @ViewChildren) lub @HostChildren(zamiast @ContentChildren) byłyby znacznie lepszymi nazwami, ponieważ w takim kontekście wszystko, o czym mówimy, jest związane z widokiem, a wiązanie wrt jest również związane z treścią.
superjos,
35
@ViewChildren== twoje własne dziecko; @ContentChildren== czyjeś dziecko
szczeryJ
107
Jak sama nazwa wskazuje, @ContentChildi @ContentChildrenzapytań powróci dyrektyw istniejących wewnątrz <ng-content></ng-content>elementu widoku, podczas gdy @ViewChildi @ViewChildrentylko patrzeć na te elementy, które na widok szablonu bezpośrednio.
Więc użyj @ViewChild (ren), chyba że masz komponenty w swoim widoku, w którym to przypadku powróć do @ContentChild (ren)?
Ben Taliadoros
31
Ten film wideo od Angular Connect zawiera doskonałe informacje o ViewChildren, ViewChild, ContentChildren i ContentChild
https://youtu.be/4YmnbGoh49U
@Component({
template: `
<my-widget>
<comp-a/>
</my-widget>
`
})
class App {}
@Component({
selector: 'my-widget',
template: `<comp-b/>`
})
class MyWidget {}
Z my-widgetperspektywy comp-ajest ContentChildi comp-bjest ViewChild. CompomentChildreni ViewChildrenzwracamy iterowalność, podczas gdy xChild zwraca pojedynczą instancję.
Teraz możesz pobrać wszystkie elementy potomne w kontekście komponentu domowego za pomocą @viewChildren, ponieważ są one dodawane bezpośrednio w szablonie komponentu domowego. Jednak podczas próby uzyskania dostępu do <small-child>elementu z kontekstu komponentu podrzędnego nie można uzyskać do niego dostępu, ponieważ nie jest on dodawany bezpośrednio w szablonie komponentu podrzędnego. Jest dodawany poprzez projekcję treści do komponentu potomnego według komponentu domowego. W tym miejscu pojawia się @contentChild i możesz go pobrać za pomocą @contentChild.
Różnica występuje, gdy próbujesz uzyskać dostęp do referencji elementów w kontrolerze. Możesz uzyskać dostęp do grab wszystkich elementów, które są bezpośrednio dodawane do szablonu komponentu przez @viewChild. Ale nie można pobrać odniesienia do rzutowanych elementów za pomocą @viewChild Aby uzyskać dostęp do rzutowanego elementu, należy użyć @contentChild.
Odpowiedzi:
Odpowiem na twoje pytanie za pomocą terminologii Shadow DOM i Light DOM (pochodzi ona z komponentów internetowych, więcej informacji tutaj ). Ogólnie:
Tak więc odpowiedź na twoje pytanie jest dość prosta:
źródło
@TemplateChildren
(zamiast@ViewChildren
) lub@HostChildren
(zamiast@ContentChildren
) byłyby znacznie lepszymi nazwami, ponieważ w takim kontekście wszystko, o czym mówimy, jest związane z widokiem, a wiązanie wrt jest również związane z treścią.@ViewChildren
== twoje własne dziecko;@ContentChildren
== czyjeś dzieckoJak sama nazwa wskazuje,
@ContentChild
i@ContentChildren
zapytań powróci dyrektyw istniejących wewnątrz<ng-content></ng-content>
elementu widoku, podczas gdy@ViewChild
i@ViewChildren
tylko patrzeć na te elementy, które na widok szablonu bezpośrednio.źródło
Ten film wideo od Angular Connect zawiera doskonałe informacje o ViewChildren, ViewChild, ContentChildren i ContentChild https://youtu.be/4YmnbGoh49U
Z
my-widget
perspektywycomp-a
jestContentChild
icomp-b
jestViewChild
.CompomentChildren
iViewChildren
zwracamy iterowalność, podczas gdy xChild zwraca pojedynczą instancję.źródło
<comp-b><ng-content></ng-content></comp-b>
rację?Weźmy przykład: Mamy jeden komponent domowy i jeden komponent potomny, a wewnątrz komponent potomny jeden mały komponent potomny.
Teraz możesz pobrać wszystkie elementy potomne w kontekście komponentu domowego za pomocą @viewChildren, ponieważ są one dodawane bezpośrednio w szablonie komponentu domowego. Jednak podczas próby uzyskania dostępu do
<small-child>
elementu z kontekstu komponentu podrzędnego nie można uzyskać do niego dostępu, ponieważ nie jest on dodawany bezpośrednio w szablonie komponentu podrzędnego. Jest dodawany poprzez projekcję treści do komponentu potomnego według komponentu domowego. W tym miejscu pojawia się @contentChild i możesz go pobrać za pomocą @contentChild.Różnica występuje, gdy próbujesz uzyskać dostęp do referencji elementów w kontrolerze. Możesz uzyskać dostęp do grab wszystkich elementów, które są bezpośrednio dodawane do szablonu komponentu przez @viewChild. Ale nie można pobrać odniesienia do rzutowanych elementów za pomocą @viewChild Aby uzyskać dostęp do rzutowanego elementu, należy użyć @contentChild.
źródło