📜  contentchildren vs viewchildren (1)

📅  最后修改于: 2023-12-03 15:14:14.845000             🧑  作者: Mango

Angular中的contentChildren vs viewChildren

在Angular中,当我们需要把子元素注入到父组件中时,我们通常会用到@ContentChildren@ViewChildren这两个装饰器。这两个装饰器都用于获取子组件或元素的引用,但是它们之间有一些不同。

@ContentChildren

@ContentChildren 装饰器用于获取组件或指令在父组件模板中,使用<ng-content>插口进行投影的所有子元素的引用。这些子元素可以是任何标签或指令。当子元素被投影时,它们不会被添加到父组件的视图树中,而是注入到父组件中。

下面是一个示例,该示例使用@ContentChildren装饰器获取了PaneComponent的所有子元素的引用。

import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { PaneComponent } from './pane.component';

@Component({
  selector: 'tab',
  template: `
    <ng-content></ng-content>
  `
})
export class TabComponent implements AfterContentInit {

  @ContentChildren(PaneComponent) panes: QueryList<PaneComponent>;

  ngAfterContentInit() {
    console.log(this.panes);
  }
}
@ViewChildren

@ViewChildren 装饰器用于获取它的子组件或元素的引用,这些子组件或元素是在当前组件的视图中动态创建或添加的。这些子元素可以是任何标签或指令。当子元素被添加到当前组件的视图树中时,它们被注入到当前组件中。

下面是一个使用@ViewChildren装饰器获取ChildComponent的所有子元素引用的示例:

import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'parent',
  template: `
    <button (click)="addChild()">Add Child</button>
    <div #childContainer></div>
  `
})
export class ParentComponent implements AfterViewInit {

  @ViewChildren(ChildComponent) children: QueryList<ChildComponent>;
  
  @ViewChild('childContainer', { read: ViewContainerRef }) childContainer: ViewContainerRef;

  addChild() {
    const factory = this.componentFactoryResolver.resolveComponentFactory(ChildComponent);
    const childComponent = factory.create(this.injector);
    this.childContainer.insert(childComponent.hostView);
  }

  ngAfterViewInit() {
    console.log(this.children);
  }
}
总结

在Angular中,我们可以使用@ContentChildren@ViewChildren装饰器来获取组件或指令的子元素引用。@ContentChildren用于获取在父组件模板中使用<ng-content>插口进行投影的所有子元素的引用,而@ViewChildren用于获取动态创建或添加到当前组件视图中的子元素的引用。

注意:在使用@ContentChildren@ViewChildren装饰器时,需要在组件中实现AfterContentInitAfterViewInit接口,以确保子元素可以被正确地注入到组件中。