【问题标题】:Add dynamic Components to ViewChildren向 ViewChildren 添加动态组件
【发布时间】:2019-02-18 08:50:55
【问题描述】:

目前,我可以像这样动态加载单个组件并将其显示在 ViewChild 中:

@Component({
   selector: '...',
   template: '<ng-container #viewRef></ng-container>'
})
export class SomeComponent {
@ViewChild('viewRef', {read: ViewContainerRef}) public viewRef;

  constructor(private compiler: Compiler) {}

  ngAfterViewInit() {
    this.compiler.compileModuleAndAllComponentsAsync(SomeModule).then((factory) =>  {
      this.componentRef = this.placeholder.createComponent(factory);
    });
  }
}

现在我想加载多个组件并在列表中动态显示它们。 ViewChildren 应该是解决这个问题的方法。问题是,ViewChildren 不允许添加新元素或在ViewChild 上创建类似于createComponent 的元素。

如何创建动态组件并将它们添加到ViewChildren

【问题讨论】:

    标签: angular


    【解决方案1】:

    您可以使用 ViewChildren 从视图 DOM 中获取元素或指令的 QueryList。每当添加、删除或移动子元素时,查询列表都会更新,查询列表的可观察更改将发出一个新值。这意味着您可以在viewRefs.changes 事件上创建订阅并使用ComponentFactoryResolver 动态加载组件。请看下面的例子:

    export class SomeComponent {
        @ViewChildren('viewRef', {read: ViewContainerRef})
        public viewRefs: QueryList<ViewContainerRef>;
    
        constructor(private componentFactoryResolver: ComponentFactoryResolver) {
        }
    
        ngAfterViewInit() {
            this.viewRefs.changes.subscribe((list: QueryList<ViewContainerRef>) => {
                list.forEach((viewRef: ViewContainerRef, index: number) => {
                    const componentFactory: ComponentFactory<any> = this.componentFactoryResolver.resolveComponentFactory(OtherComponent);
                    viewRef.createComponent(componentFactory, index);
                });
            });
        }
    }
    

    【讨论】:

    • 这按预期工作,谢谢!我只是不能 100% 确定我实际订阅的内容。 changes 何时触发?
    • 任何时候添加、删除或移动子元素,查询列表都会更新,查询列表的可观察变化将发出一个新值。
    • 但这也意味着 viewChildren 中的每个动态组件都会被一个新组件替换,只要从列表中添加/删除某些内容对吗?
    • 正确。所有动态组件都收集到列表中。您订阅该列表中的任何更改,并且发出的值是一个包含子组件实际状态的新列表
    猜你喜欢
    • 2017-08-23
    • 2016-11-11
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    相关资源
    最近更新 更多