@ViewChild 和@ContentChild 有什么区别?
What's the difference between @ViewChild and @ContentChild?
Angular 2 提供了 @ViewChild
、@ViewChildren
、@ContentChild
和 @ContentChildren
装饰器,用于查询组件的后代元素。
前两者和后两者有什么区别?
顾名思义,@ContentChild
和 @ContentChildren
查询将 return 指令存在于视图的 <ng-content></ng-content>
元素中,而 @ViewChild
和 @ViewChildren
只直接查看视图模板上的元素。
我会用 Shadow DOM 和 Light DOM 术语来回答你的问题(它已经来了来自网络组件,查看更多 here)。总的来说:
- Shadow DOM - 是组件的内部 DOM 定义 由您(作为组件的创建者)编写,并且对最终用户隐藏。例如:
@Component({
selector: 'some-component',
template: `
<h1>I am Shadow DOM!</h1>
<h2>Nice to meet you :)</h2>
<ng-content></ng-content>
`;
})
class SomeComponent { /* ... */ }
- Light DOM - 是 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 { /* ... */ }
所以,你的问题的答案很简单:
The difference between @ViewChildren
and @ContentChildren
is that @ViewChildren
look for elements in Shadow DOM while @ContentChildren
look for them in Light DOM.
这个来自 Angular Connect 的视频包含关于 ViewChildren、ViewChild、ContentChildren 和 ContentChild 的精彩信息
https://youtu.be/4YmnbGoh49U
@Component({
template: `
<my-widget>
<comp-a/>
</my-widget>
`
})
class App {}
@Component({
selector: 'my-widget',
template: `<comp-b/>`
})
class MyWidget {}
从my-widget
的角度来看,comp-a
是ContentChild
,comp-b
是ViewChild
。 CompomentChildren
和 ViewChildren
return 可迭代,而 xChild return 是单个实例。
举个例子,我们有一个 home 组件和一个子组件,在子组件内部有一个小子组件。
<home>
<child>
<small-child><small-child>
</child>
</home>
现在你可以使用@viewChildren 抓取 home 组件上下文中的所有子元素,因为它们是直接添加到 home 组件的模板中的。
但是,当您尝试从子组件的上下文访问 <small-child>
元素时,您将无法访问它,因为它没有直接添加到子组件模板中。
它是由 home 组件通过内容投影添加到子组件中的。
这就是@contentChild 的用武之地,您可以使用@contentChild 获取它。
当您尝试访问控制器中的元素引用时会出现差异。
您可以访问通过@viewChild 直接添加到组件模板中的所有元素。
但是您不能使用@viewChild 获取投影元素引用
要访问投影元素,您必须使用 @contentChild.
只需将 ViewChildren 重命名为 InternalChildren,将 ContentChildren 重命名为 ExternalChildren
Angular 2 提供了 @ViewChild
、@ViewChildren
、@ContentChild
和 @ContentChildren
装饰器,用于查询组件的后代元素。
前两者和后两者有什么区别?
顾名思义,@ContentChild
和 @ContentChildren
查询将 return 指令存在于视图的 <ng-content></ng-content>
元素中,而 @ViewChild
和 @ViewChildren
只直接查看视图模板上的元素。
我会用 Shadow DOM 和 Light DOM 术语来回答你的问题(它已经来了来自网络组件,查看更多 here)。总的来说:
- Shadow DOM - 是组件的内部 DOM 定义 由您(作为组件的创建者)编写,并且对最终用户隐藏。例如:
@Component({
selector: 'some-component',
template: `
<h1>I am Shadow DOM!</h1>
<h2>Nice to meet you :)</h2>
<ng-content></ng-content>
`;
})
class SomeComponent { /* ... */ }
- Light DOM - 是 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 { /* ... */ }
所以,你的问题的答案很简单:
The difference between
@ViewChildren
and@ContentChildren
is that@ViewChildren
look for elements in Shadow DOM while@ContentChildren
look for them in Light DOM.
这个来自 Angular Connect 的视频包含关于 ViewChildren、ViewChild、ContentChildren 和 ContentChild 的精彩信息 https://youtu.be/4YmnbGoh49U
@Component({
template: `
<my-widget>
<comp-a/>
</my-widget>
`
})
class App {}
@Component({
selector: 'my-widget',
template: `<comp-b/>`
})
class MyWidget {}
从my-widget
的角度来看,comp-a
是ContentChild
,comp-b
是ViewChild
。 CompomentChildren
和 ViewChildren
return 可迭代,而 xChild return 是单个实例。
举个例子,我们有一个 home 组件和一个子组件,在子组件内部有一个小子组件。
<home>
<child>
<small-child><small-child>
</child>
</home>
现在你可以使用@viewChildren 抓取 home 组件上下文中的所有子元素,因为它们是直接添加到 home 组件的模板中的。
但是,当您尝试从子组件的上下文访问 <small-child>
元素时,您将无法访问它,因为它没有直接添加到子组件模板中。
它是由 home 组件通过内容投影添加到子组件中的。
这就是@contentChild 的用武之地,您可以使用@contentChild 获取它。
当您尝试访问控制器中的元素引用时会出现差异。 您可以访问通过@viewChild 直接添加到组件模板中的所有元素。 但是您不能使用@viewChild 获取投影元素引用 要访问投影元素,您必须使用 @contentChild.
只需将 ViewChildren 重命名为 InternalChildren,将 ContentChildren 重命名为 ExternalChildren