ChatGPT解决这个技术问题 Extra ChatGPT

@ViewChild 和 @ContentChild 有什么区别?

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

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

阅读以下答案后,此链接帮助了我blog.mgechev.com/2016/01/23/…。干杯:)

m
mimo

我将使用 Shadow DOMLight 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 { /* ... */ }

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

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


Minko Gechew 的博客条目 blog.mgechev.com/2016/01/23/… 对我来说更有意义。 @ContentChildren 是通过内容投影插入的孩子(在 <ng-content></ng-content> 之间的孩子)。来自 Minkos 博客:“另一方面,在给定组件的宿主元素的开始标签和结束标签之间使用的 ** 元素称为 *content children **。” Angular2 中的 Shadow DOM 和视图封装在此处描述:blog.thoughtram.io/angular/2015/06/29/…
对我来说,听起来 @TemplateChildren(而不是 @ViewChildren)或 @HostChildren(而不是 @ContentChildren)会是更好的名称,因为在这样的上下文中,我们谈论的一切都是与视图相关的,并且wrt 绑定也与内容相关。
@ViewChildren == 你自己的孩子; @ContentChildren == 别人的孩子
@candidJ 今天这是 False,在 ContentChildren 中,您有一个默认为 {descendants: false} 的标志。所以等价是不正确的。
@ViewChild 和 @ContentChild 呢?
d
drew moore

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


所以使用@ViewChild(ren) 除非你的视图中有组件,在这种情况下会退回到@ContentChild(ren)?
m
mithun_daa

这个来自 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-bViewChildCompomentChildrenViewChildren 返回一个可迭代对象,而 xChild 返回一个实例。


这是更好的解释。谢谢 :)
您做了一个简单明了的示例,但 MyWidget 的模板应该是 <comp-b><ng-content></ng-content></comp-b> 对吗?
J
Jaqen H'ghar

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

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

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

当您尝试访问控制器中的元素引用时,就会出现差异。您可以访问通过@viewChild 直接添加到组件模板中的所有元素。但是您不能使用@viewChild 获取投影元素引用要访问投影元素,您必须使用@contentChild。


H
Howard

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