@ViewChild和@ContentChild有什么区别?

时间:2015-12-17 04:41:21

标签: angular

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

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

5 个答案:

答案 0 :(得分:215)

我将使用 Shadow DOM Light DOM 术语来回答您的问题(它来自网络组件,请参阅here)。一般来说:

  • Shadow DOM - 是您的 定义的组件的内部DOM(作为组件的创建者< / strong>)并从最终用户隐藏。例如:
@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 { /* ... */ }

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

  

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

答案 1 :(得分:90)

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

答案 2 :(得分:25)

来自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-aContentChildcomp-bViewChild。 <{1}}和CompomentChildren返回一个iterable,而xChild返回一个实例。

答案 3 :(得分:0)

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

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

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

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

答案 4 :(得分:0)

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