@ViewChild和@ContentChild有什么区别?

Angular 2提供了@ViewChild@ViewChildren@ContentChild@ContentChildren装饰器,用于查询组件的子元素。

前两个和后两个有什么区别?

117881 次浏览

顾名思义,@ContentChild@ContentChildren查询将返回存在于视图的<ng-content></ng-content>元素中的指令,而@ViewChild@ViewChildren只直接查看视图模板中的元素。

我将使用DOM的影子光DOM术语来回答你的问题(它来自web组件,请参阅更多在这里)。一般来说:

  • 影子DOM < em > < / em > -是组件的内部DOM,定义为由你(作为组件的创建者),并对最终用户隐藏。例如:
@Component({
selector: 'some-component',
template: `
<h1>I am Shadow DOM!</h1>
<h2>Nice to meet you :)</h2>
<ng-content></ng-content>
`;
})
class SomeComponent { /* ... */ }
  • < em >光DOM < / em > -是组件的最终用户提供给组件的DOM。例如:
@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 { /* ... */ }

所以,你问题的答案很简单:

@ViewChildren@ContentChildren的区别在于@ViewChildren在Shadow DOM中查找元素,而@ContentChildren在Light DOM中查找元素。

这个来自Angular Connect的视频提供了关于ViewChildren、ViewChild、ContentChildren和ContentChild的精彩信息 https://youtu.be/4YmnbGoh49U < / p >
@Component({
template: `
<my-widget>
<comp-a/>
</my-widget>
`
})
class App {}


@Component({
selector: 'my-widget',
template: `<comp-b/>`
})
class MyWidget {}

my-widget的角度来看,comp-aContentChild,而comp-bViewChildCompomentChildrenViewChildren返回一个可迭代对象,而xChild返回一个实例。

让我们举个例子,我们有一个家庭组件和一个子组件,在子组件内部有一个小的子组件。

<home>
<child>
<small-child><small-child>
</child>
</home>
现在你可以用@viewChildren在home组件的上下文中抓取所有的子元素,因为这些子元素直接添加到home组件的模板中。 但是,当你试图从子组件的上下文访问<small-child>元素时,你不能访问它,因为它没有直接添加到子组件模板中。 它是由家组件通过内容投影添加到子组件中的。 这就是@contentChild的作用,你可以用@contentChild来抓取它 当你试图访问控制器中的元素引用时,会发生差异。 你可以通过@viewChild获取所有直接添加到组件模板中的元素。 但是你不能用@viewChild获取投影元素引用 要访问投影元素,你必须使用@contentChild.

只需将ViewChildren重命名为InternalChildren,将ContentChildren重命名为ExternalChildren