角动态分量注入错误 [英] Angular Dynamic Component Injection error

查看:146
本文介绍了角动态分量注入错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个小型参考应用程序,以查看如何在一个组件中动态注入组件以查看页面上的内容.我收到一个指向ViewContainerRef对象的错误.

I'm building a small reference application to see how to dynamically inject components in one component to view the content on the page. I'm getting an error that points to the ViewContainerRef object.

这是应该在视图中显示注入的组件内容的组件,但是会引发错误:

This is the component that should display the injected component's content in the view, but it's throwing an error:

以下是引发错误的StatsComponent:

Here is the StatsComponent that is throwing the error:

export class StatsComponent implements AfterViewInit, OnDestroy {
  @Input() dynComp: DynamicComponent;
  @ViewChild(ComponentHostDirective) appComponentHost: ComponentHostDirective;
  componentRef: ComponentRef<any>;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

  ngAfterViewInit() {
    this.loadComponent();
  }

  ngOnDestroy() {
    this.componentRef.destroy();
  }

  loadComponent() {
    console.log('inside stats component: ', this.dynComp);
    const comp = this.dynComp;
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(comp.component);
    console.log('host: ', this.appComponentHost);  // <-- this is undefined

    const viewContainerRef = this.appComponentHost.viewContainerRef;
    viewContainerRef.clear();

    this.componentRef = viewContainerRef.createComponent(componentFactory);
    (<DynamicComponent>this.componentRef.instance).data = comp.data;
  }

}

我有一个正在运行的演示此处,还有一个

I have a working demo here, and a github project.

为什么未引用容器?

[更新]:现在可以使用!转到我的演示和github项目以查看实际效果.

[UPDATE]: this now works! Go to my demo and github project to see it in action.

推荐答案

Angular无法识别模板中的@ViewChild(ComponentHostDirective),因为您没有将ComponentHostDirective指令包括在用于编译StatsComponent的指令列表中:

Angular can't recognize @ViewChild(ComponentHostDirective) in your template because you didn't include ComponentHostDirective directive to list of directives that are used to compile StatsComponent:

要了解angular用于编译角度模板的指令,请查看以下答案

To understand which directives angular uses to compile angular template take a look at this answer Angular 2 Use component from another module (see diagram)

我知道您已经在AppModule中声明了ComponentHostDirective.但是您的StatsComponentHomeModule中声明,并且该模块对ComponentHostDirective一无所知. 我们必须在HomeModule中声明或导入此指令.

I know you have already declared ComponentHostDirective within AppModule. But your StatsComponent is declared within HomeModule and this module knows nothing about ComponentHostDirective. We have to declare or import this directive in HomeModule.

如果我们在HomeModule中声明ComponentHostDirective,则会收到错误消息

If we will declare ComponentHostDirective in HomeModule we get the error

类型ComponentHostDirective是2个模块的声明的一部分: AppModule和HomeModule!

Type ComponentHostDirective is part of the declarations of 2 modules: AppModule and HomeModule!

SharedModule进行了救援:

src/app/shared/shared.module.ts

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [
    ComponentHostDirective
  ],
  exports: [
    CommonModule,
    ComponentHostDirective
  ]
})
export class SharedModule {}

app.module.ts

@NgModule({
  declarations: [
    ComponentHostDirective <== remove it
  ],
  imports: [
    ...
    SharedModule, // add this
    ...
  ]
})
export class AppModule { }

home.module.ts

@NgModule({
  imports: [
    ...
    SharedModule, // add this
    ...
  ]
})
export class HomeModule { }

之后,您的appComponentHost属性将引用ComponentHostDirective实例.

After that your appComponentHost property will refer to ComponentHostDirective instance.

此外,您还会收到错误

ExpressionChangedAfterItHasBeenCheckedError:表达式已更改 经过检查后.上一个值:未定义".当前值: 客户".

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'Customers'.

创建组件后.

请勿更改ngAfterViewInit挂钩中的绑定.使用ngOnInit代替:

Don't change bindings within ngAfterViewInit hook. Use ngOnInit instead:

export class StatsComponent implements OnInit, OnDestroy {
  ...
  ngOnInit() {
    this.loadComponent();
  }

文章您所需的一切了解ExpressionExpressdAfterItHaHasBeenCheckedError错误详细说明了该行为(感谢@Maximus).

The article Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedError error explains the behavior in great details (Thank's @Maximus).

最后,您将看到结果:

这篇关于角动态分量注入错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆