错误而重新使用已经加载在飞行组件(Error While Reusing Component Tha

2019-10-28 12:58发布

我创建了与从我正在添加的服务器这样的主题模板,在飞行加载子组件的组件

在角类似$ 4/5东西角JS编译编译动态HTML

我想打电话给在我的应用程序的任何地方这个组件,它的选择可以从模式的模板( 我不能重新加载模态多时间 )调用,它可以从浏览器调用( 我不能在同时加载模式和浏览器同一时间

@Component({
  selector: 'my-component',
  template: `<h2>Stuff bellow will get dynamically created and injected<h2>
          <div #vc></div>`
})
export class TaggedDescComponent {
  @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;

  private cmpRef: ComponentRef<any>;

  constructor(private compiler: Compiler,
              private injector: Injector,
              private moduleRef: NgModuleRef<any>,
              private backendService: backendService,
              ) {}

  ngAfterViewInit() {
    // Here, get your HTML from backend.
    this.backendService.getHTMLFromServer()
        .subscribe(rawHTML => this.createComponentFromRaw(rawHTML));
  }

  // Here we create the component.
  private createComponentFromRaw(template: string) {
    // Let's say your template looks like `<h2><some-component [data]="data"></some-component>`
    // As you see, it has an (existing) angular component `some-component` and it injects it [data]

    // Now we create a new component. It has that template, and we can even give it data.
    const tmpCmp = Component({ template, styles })(class {
      // the class is anonymous. But it's a quite regular angular class. You could add @Inputs,
      // @Outputs, inject stuff etc.
      data: { some: 'data'};
      ngOnInit() { /* do stuff here in the dynamic component */}
    });

    // Now, also create a dynamic module.
    const tmpModule = NgModule({
      imports: [RouterModule],
      declarations: [tmpCmp],
      // providers: [] - e.g. if your dynamic component needs any service, provide it here.
    })(class {});

    // Now compile this module and component, and inject it into that #vc in your current component template.
    this.compiler.compileModuleAndAllComponentsAsync(tmpModule)
      .then((factories) => {
        const f = factories.componentFactories[0];
        this.cmpRef = f.create(this.injector, [], null, this.moduleRef);
        this.cmpRef.instance.name = 'my-dynamic-component';
        this.vc.insert(this.cmpRef.hostView);
      });
  }

  // Cleanup properly. You can add more cleanup-related stuff here.
  ngOnDestroy() {
    if(this.cmpRef) {
      this.cmpRef.destroy();
    }
  }
}

但是,当这部分reloadded(而无需刷新浏览器)我有这样的错误:

ERROR Error: Type e is part of the declarations of 2 modules: function(){} and function(){}! Please consider moving e to a higher module that imports function(){} and function(){}. You can also create a new NgModule that exports and includes e then import that NgModule in function(){} and function(){}.
    at le (main.js:1)
    at e._addTypeToModule (main.js:1)
    at main.js:1
    at Array.forEach (<anonymous>)
    at e.getNgModuleMetadata (main.js:1)
    at e._loadModules (main.js:1)
    at e._compileModuleAndAllComponents (main.js:1)
    at e.compileModuleAndAllComponentsAsync (main.js:1)
    at e.compileModuleAndAllComponentsAsync (main.js:1)
    at e.createComponentFromRaw (main.js:1)

Answer 1:

既然你要动态地呈现组件需要在部件需要进口,并且需要相同的组件父模块中注册。

如果你想从别的地方的应用都使用相同的组件,但是会导致一些问题,这对他们的一些解决方法。 您可以按照下面的文章,了解更多关于一样, https://blog.angularindepth.com/here-is-what-you-need-to-know-about-dynamic-components-in-angular-ac1e96167f9e

但这一过程变得相当复杂,我会强烈建议你使用它可以重新加入到角CDK门户网站,门户是一块UI的,可以动态地呈现在网页上的开口槽。 的“片UI的”可以是一个组件或TemplateRef和“开槽”是PortalHost。

有上同一个不错的表象视频。

https://www.youtube.com/watch?v=YQMIR01dQew

希望这有助于,万事如意!



文章来源: Error While Reusing Component That Have Been Loaded On The fly