Contestaré su pregunta usando la terminología de Shadow DOM y Light DOM (proviene de componentes web, vea más aquí ) En general:
Shadow DOM : es un DOM interno de su componente definido por usted (como creador del componente ) y oculto a un usuario final. Por ejemplo:
@Component({
selector:'some-component',
template:`<h1>I am Shadow DOM!</h1><h2>Nice to meet you :)</h2><ng-content></ng-content>`;})classSomeComponent{/* ... */}
DOM ligero : es un DOM que un usuario final de su componente suministra a su componente. Por ejemplo:
@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{/* ... */}
Entonces, la respuesta a tu pregunta es bastante simple:
La diferencia entre @ViewChildreny @ContentChildrenes que @ViewChildrenbusca elementos en Shadow DOM mientras los @ContentChildrenbusca en Light DOM.
La entrada de blog blog.mgechev.com/2016/01/23/… de Minko Gechew tiene más sentido para mí. @ContentChildren son los hijos, insertados por proyección de contenido (los hijos entre <ng-content> </ng-content>). Desde el blog de Minkos: "Por otro lado, los elementos ** que se usan entre las etiquetas de apertura y cierre del elemento host de un componente dado se denominan * contenido hijos **". Aquí se describe Shadow DOM y encapsulación de vistas en Angular2: blog.thoughtram.io/angular/2015/06/29/… .
Westor
44
Para mí, parece que @TemplateChildren(en lugar de @ViewChildren) o @HostChildren(en lugar de @ContentChildren) habrían sido nombres mucho mejores, ya que en ese contexto todo lo que estamos hablando está relacionado con la vista, y el enlace wrt también está relacionado con el contenido.
superjos
35
@ViewChildren== tu propio hijo; @ContentChildren== hijo de otra persona
candidJ
107
Como su nombre indica, @ContentChildy @ContentChildrenlas consultas volverán directivas existentes en el interior del <ng-content></ng-content>elemento de la vista, mientras que @ViewChildy @ViewChildrensólo se ven en los elementos que están en su plantilla de vista directa.
Entonces, use @ViewChild (ren) a menos que tenga componentes en su vista, en cuyo caso recurrirá a @ContentChild (ren)?
Ben Taliadoros
31
Este video de Angular Connect tiene excelente información sobre ViewChildren, ViewChild, ContentChildren y ContentChild
https://youtu.be/4YmnbGoh49U
@Component({
template: `
<my-widget>
<comp-a/>
</my-widget>
`
})
class App {}
@Component({
selector: 'my-widget',
template: `<comp-b/>`
})
class MyWidget {}
Desde my-widgetla perspectiva de, comp-aes el ContentChildy comp-bes el ViewChild. CompomentChildreny ViewChildrendevuelve un iterable mientras que xChild devuelve una sola instancia.
Ahora puede tomar todos los elementos secundarios en el contexto del componente de inicio con @viewChildren porque estos se agregan directamente en la plantilla del componente de inicio. Pero, cuando intenta acceder al <small-child>elemento desde el contexto del componente secundario, no puede acceder a él porque no se agrega directamente dentro de la plantilla del componente secundario. Se agrega a través de la proyección de contenido en el componente secundario por componente de inicio. Aquí es donde entra @contentChild y puedes tomarlo con @contentChild.
La diferencia ocurre cuando intenta acceder a elementos de referencia en el controlador. Puede acceder a tomar todos los elementos que @viewChild agrega directamente a la plantilla del componente. Pero no puede tomar la referencia de elementos proyectados con @viewChild Para acceder al elemento proyectado, debe usar @contentChild.
Respuestas:
Contestaré su pregunta usando la terminología de Shadow DOM y Light DOM (proviene de componentes web, vea más aquí ) En general:
Entonces, la respuesta a tu pregunta es bastante simple:
fuente
@TemplateChildren
(en lugar de@ViewChildren
) o@HostChildren
(en lugar de@ContentChildren
) habrían sido nombres mucho mejores, ya que en ese contexto todo lo que estamos hablando está relacionado con la vista, y el enlace wrt también está relacionado con el contenido.@ViewChildren
== tu propio hijo;@ContentChildren
== hijo de otra personaComo su nombre indica,
@ContentChild
y@ContentChildren
las consultas volverán directivas existentes en el interior del<ng-content></ng-content>
elemento de la vista, mientras que@ViewChild
y@ViewChildren
sólo se ven en los elementos que están en su plantilla de vista directa.fuente
Este video de Angular Connect tiene excelente información sobre ViewChildren, ViewChild, ContentChildren y ContentChild https://youtu.be/4YmnbGoh49U
Desde
my-widget
la perspectiva de,comp-a
es elContentChild
ycomp-b
es elViewChild
.CompomentChildren
yViewChildren
devuelve un iterable mientras que xChild devuelve una sola instancia.fuente
<comp-b><ng-content></ng-content></comp-b>
correcta.Tomemos un ejemplo: tenemos un componente principal y un componente secundario y dentro del componente secundario un componente secundario pequeño.
Ahora puede tomar todos los elementos secundarios en el contexto del componente de inicio con @viewChildren porque estos se agregan directamente en la plantilla del componente de inicio. Pero, cuando intenta acceder al
<small-child>
elemento desde el contexto del componente secundario, no puede acceder a él porque no se agrega directamente dentro de la plantilla del componente secundario. Se agrega a través de la proyección de contenido en el componente secundario por componente de inicio. Aquí es donde entra @contentChild y puedes tomarlo con @contentChild.La diferencia ocurre cuando intenta acceder a elementos de referencia en el controlador. Puede acceder a tomar todos los elementos que @viewChild agrega directamente a la plantilla del componente. Pero no puede tomar la referencia de elementos proyectados con @viewChild Para acceder al elemento proyectado, debe usar @contentChild.
fuente