Angular 2 proporciona @ViewChild
, @ViewChildren
, @ContentChild
y @ContentChildren
decoradores para consultar elementos descendientes de un componente.
¿Cuál es la diferencia entre los dos primeros y los dos últimos?
Angular 2 proporciona @ViewChild
, @ViewChildren
, @ContentChild
y @ContentChildren
decoradores para consultar elementos descendientes de un componente.
¿Cuál es la diferencia entre los dos primeros y los dos últimos?
Respuestas:
Contestaré su pregunta usando la terminología de Shadow DOM y Light DOM (proviene de componentes web, vea más aquí ) En general:
@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 { /* ... */ }
Entonces, la respuesta a tu pregunta es bastante simple:
La diferencia entre
@ViewChildren
y@ContentChildren
es que@ViewChildren
busca elementos en Shadow DOM mientras los@ContentChildren
busca en Light DOM.
@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 persona
Como 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.
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-widget
la perspectiva de, comp-a
es el ContentChild
y comp-b
es el ViewChild
. CompomentChildren
y ViewChildren
devuelve un iterable mientras que xChild devuelve una sola instancia.
<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.
<home>
<child>
<small-child><small-child>
</child>
</home>
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.