@ViewChild和@ContentChild有什么区别?


Answers:


254

我将使用Shadow DOMLight DOM术语回答您的问题(它来自Web组件,请参见此处)。一般来说:

  • 影子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 { /* ... */ }
  • 轻型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 { /* ... */ }

因此,您的问题的答案非常简单:

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


10
Minko Gechew 的博客文章blog.mgechev.com/2016/01/23/…对我来说更有意义。@ContentChildren是由内容投影插入的子项(<ng-content> </ ng-content>之间的子项)。来自Minkos Blog:“另一方面,在给定组件的宿主元素的开始和结束标记之间使用的**元素称为* content子元素**。” 此处介绍了Angular2中的Shadow DOM和视图封装:blog.thoughtram.io/angular/2015/06/29/…
Westor

4
对我来说听起来像@TemplateChildren(而不是@ViewChildren)或 @HostChildren(而不是@ContentChildren)应该是更好的名称,因为在这种情况下,我们正在谈论的所有内容都与视图相关,而wrt绑定也与内容相关。
superjos

34
@ViewChildren==你自己的孩子;@ContentChildren==某人的另一个孩子
candidJ

106

正如其名,@ContentChild@ContentChildren查询将返回现有的内部指令<ng-content></ng-content>视图的元素,而@ViewChild@ViewChildren不仅要看直接对你的视图模板元素。


因此,除非您的视图中有组件,否则请使用@ViewChild(ren)?
Ben Taliadoros

31

从这个角度连接视频大约有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-aContentChildcomp-bViewChildCompomentChildrenViewChildren返回一个可迭代的,而xChild返回单个实例。


这是更好的解释。谢谢:)
坠毁了

您已经做了一个简单明了的示例,但是MyWidget的模板应该 <comp-b><ng-content></ng-content></comp-b>正确吗?
arjel

1

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

<home>
     <child>
           <small-child><small-child>
     </child>
</home>

现在,您可以使用@viewChildren来获取home组件上下文中的所有子元素,因为这些元素直接添加到home组件的模板中。但是,当您尝试访问<small-child>从子组件的上下文元素时,您将无法访问它,因为它没有直接添加到子组件模板中。通过内容投影将其添加到home组件的子组件中。这是@contentChild出现的地方,您可以使用@contentChild进行抓取。

当您尝试访问控制器中的元素引用时,会发生区别。您可以访问获取由@viewChild直接添加到组件模板中的所有元素。但是您不能使用@viewChild来获取投影元素引用。要访问投影元素,您必须使用@contentChild。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.