Angular 2 动态组件加载 ngOnChanges 生命周期钩子调用

Posted

技术标签:

【中文标题】Angular 2 动态组件加载 ngOnChanges 生命周期钩子调用【英文标题】:Angular 2 Dynamic Component loading ngOnChanges lifecycle hook call 【发布时间】:2017-03-29 09:36:16 【问题描述】:

在动态组件加载的情况下不调用 ngOnChanges 生命周期钩子是预期的行为吗? 只为我调用了构造函数 ngOnInit 和 ngAfterViewInit。但是根据docs 应该在ngOnInit 之前调用它。

我正在加载这样的组件:

@ViewChild('place',  read: ViewContainerRef ) container: ViewContainerRef;

   private componentRef: ComponentRef<MyLoggerComponent>;

   constructor(private componentFactoryResolver: ComponentFactoryResolver)  

   ngAfterViewInit() 
     const componentFactory: ComponentFactory<any> = this.componentFactoryResolver.resolveComponentFactory(MyLoggerComponent);
     this.componentRef = this.container.createComponent(componentFactory);
     this.componentRef.changeDetectorRef.detectChanges();
   

Plunker

【问题讨论】:

ngOnChanges() 仅在 Angular 绑定更新输入且动态创建的组件不支持 @Input() 或 @Output() 时调用 如果常规组件具有@Input 属性并且它已更新,它将触发 ngOnchange 此 plunker 将无法工作 plnkr.co/edit/w2Cc1ssw30ZcP0M2gFdJ?p=preview 这是带有常规组件的工作 plunker plnkr.co/edit/sFl84z0XY6OpCa5imTvz?p=preview 另见此线程github.com/angular/angular/issues/8903 【参考方案1】:

根据讨论,https://github.com/angular/angular/issues/8903 动态组件加载不应在子组件中触发 ngOnChanges,即使在调用 detectChanges 之后也是如此,因为此事件仅为模板绑定保留。

如果您的子组件仅以动态方式加载,您可以使用 javascript setter 而不是ngOnChanges。示例如下:

export class DynamicallyLoadedComponent 
  private _property: string;
  get property(): string  return this._property; 
  set property(newVal: string) 
    if (this._property === newVal)  return; 
    this._property = newVal;

    this.onChanges();  // instead of ngOnChanges
  

【讨论】:

想知道为什么他们限制使用ngOnChanges 绑定进行模板绑定。 @sirwojtek 你有可以工作的示例代码吗? @SirWojtek 在这个例子中你使用的是什么版本的角度? @Rich 它正在使用 5.2.4 版本(可能更早) @aguetat 解决方案来自我公司代码,将尝试提取 Plunker

以上是关于Angular 2 动态组件加载 ngOnChanges 生命周期钩子调用的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 - 使用 ComponentResolver 加载在运行时下载的组件

Angular 5 - 动态组件模板加载

Angular - 动态加载选项卡名称和组件

从 Angular 组件动态加载外部 javascript 文件

在 Angular 中为动态加载的组件提供 @input

在Angular中动态加载组件[重复]