Angular 2 proporciona @ViewChild
, @ViewChildren
, @ContentChild
e @ContentChildren
decoradores para consultar elementos descendentes de um componente.
Qual é a diferença entre os dois primeiros e os dois últimos?
Angular 2 proporciona @ViewChild
, @ViewChildren
, @ContentChild
e @ContentChildren
decoradores para consultar elementos descendentes de um componente.
Qual é a diferença entre os dois primeiros e os dois últimos?
Respostas:
Responderei sua pergunta usando as terminologias Shadow DOM e Light DOM (elas vieram de componentes da Web, veja mais aqui ). Em geral:
@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 { /* ... */ }
Portanto, a resposta para sua pergunta é bem simples:
A diferença entre
@ViewChildren
e@ContentChildren
é@ViewChildren
procurar elementos no Shadow DOM e@ContentChildren
procurá-los no Light DOM.
@TemplateChildren
(em vez de @ViewChildren
) ou @HostChildren
(em vez de @ContentChildren
) teriam nomes muito melhores, pois nesse contexto tudo o que estamos falando é relacionado à exibição e a ligação wrt também está relacionada ao conteúdo.
@ViewChildren
== seu próprio filho; @ContentChildren
== alguém de outra criança
Como o nome sugere, @ContentChild
e @ContentChildren
consultas retornará directivas existentes no interior do <ng-content></ng-content>
elemento de sua vista, enquanto @ViewChild
e @ViewChildren
só olhar para os elementos que estão no seu modelo de visão diretamente.
Este vídeo do Angular Connect tem informações excelentes sobre ViewChildren, ViewChild, ContentChildren e ContentChild https://youtu.be/4YmnbGoh49U
@Component({
template: `
<my-widget>
<comp-a/>
</my-widget>
`
})
class App {}
@Component({
selector: 'my-widget',
template: `<comp-b/>`
})
class MyWidget {}
Da my-widget
perspectiva de, comp-a
é o ContentChild
e comp-b
é o ViewChild
. CompomentChildren
e ViewChildren
retorne um iterável enquanto o xChild retorna uma única instância.
<comp-b><ng-content></ng-content></comp-b>
certo?
Vamos dar um exemplo: temos um componente doméstico e um componente filho e, dentro do componente filho, um componente filho pequeno.
<home>
<child>
<small-child><small-child>
</child>
</home>
Agora você pode pegar todos os elementos filhos no contexto do componente inicial com @viewChildren, porque eles são adicionados diretamente no modelo do componente inicial. Mas, quando você tenta acessar o <small-child>
elemento do contexto do componente filho, não é possível acessá-lo porque ele não é adicionado diretamente ao modelo do componente filho. É adicionado através da projeção de conteúdo no componente filho pelo componente inicial. É aqui que o @contentChild entra e você pode acessá-lo com @contentChild.
A diferença ocorre quando você tenta acessar a referência de elementos no controlador. Você pode acessar todos os elementos que são adicionados diretamente ao modelo do componente pelo @viewChild. Mas você não pode pegar a referência de elementos projetados com @viewChild Para acessar o elemento projetado, você deve usar @contentChild.