簡體   English   中英

Angular:如何在動態組件中使用共享模塊?

[英]Angular: How to use shared modules in a Dynamic Component?

我正在使用相同的以下代碼使用Angular編譯器的compileModuleAndAllComponentsAsync在Angular v6中創建動態組件。

viewChangeMethod(view: string) {
    let template = `<span>${view} </span>`;
    const tmpCmp = Component({ template: template })(class { });
    this._compiler.clearCacheFor(this.tmpModule)
    this.tmpModule = NgModule({ declarations: [tmpCmp,FRAComponent],import:[ComonModule] })(class {
    });

    this._compiler.compileModuleAndAllComponentsAsync(this.tmpModule)
        .then((factories) => {
            const f = factories.componentFactories[0];
            const cmpRef = f.create(this._injector, [], null, this._m);
            this._container.detach()
            console.log(cmpRef.hostView)
            this._container.insert(cmpRef.hostView);
        })
    this._compiler.clearCacheFor(this.tmpModule)
}

一切正常,但是在導入任何共享模塊或自定義模塊時出現以下錯誤。

在此處輸入圖片說明

如果您需要共享模塊或動態組件的任何其他模塊,我建議您采用稍微不同的方法來創建動態組件。

我的項目使用動態組件,並且還將各種模塊導入其中,但是我使用了以下方法來創建組件- 完全正常工作的StackBlitz

上面是我創建的StackBlitz示例,如果您想根據需要進行調整|| 下面是代碼的副本。

import {
  Component, ViewChild, AfterContentInit, ComponentFactoryResolver,
  Compiler, ViewContainerRef, NgModule, NgModuleRef
} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@Component({
  selector: 'app',
  template: '<ng-template #vc></ng-template>',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterContentInit {
  @ViewChild('vc', { read: ViewContainerRef }) _container: ViewContainerRef;
  private cmpRef;

  constructor(
    private componentFactoryResolver: ComponentFactoryResolver,
    private compiler: Compiler,
    private _m: NgModuleRef<any>) { }


  ngAfterContentInit() {
    this.addComponent();
  }

  public sayHello(): void{
    alert("Hello!");
  }

  private addComponent(): void {
    @Component({
      template: `<h2>This is a dynamic component</h2>
      <button (click)="_parent.sayHello()">Click me!</button>`
    })
    class DynamicComponent {
      constructor(public _parent: AppComponent) { }
    }
    @NgModule({
      imports: [
        BrowserModule
      ],
      declarations: [DynamicComponent],
    }) class DynamicModule { }

    const mod = this.compiler.compileModuleAndAllComponentsSync(DynamicModule);
    const factory = mod.componentFactories.find((comp) =>
      comp.componentType === DynamicComponent
    );
    this.cmpRef = this._container.createComponent(factory);
  }

}

您可以按照下面的解決方案完成工作,我已經驗證了它的早期NG版本,可以嘗試將其集成到解決方案中。

定義這樣的服務

import { Injectable, Type, Component, ComponentFactoryResolver, ViewContainerRef, ComponentRef, QueryList, ComponentFactory } from '@angular/core';

@Injectable()
export class DynamicComponentService {
    constructor(private componentFactoryResolver: ComponentFactoryResolver) {
    }

    public append(componentType: Type<any>, where: ViewContainerRef): ComponentRef<any> {
        const componentFactory = this.resolveFactory(componentType);
        const componentRef = where.createComponent(componentFactory);
        return componentRef;
    }

    public resolve (componentType: Type<any>): ComponentFactory<any> {
        const componentFactory: ComponentFactory<any> = this.componentFactoryResolver.resolveComponentFactory(componentType);
        return componentFactory;
    }
}

以上服務負責動態注入您的組件。

還要注意,您不需要將組件作為字符串傳遞,而需要傳遞其類型。

在實施之前,請仔細閱讀上述課程。

用法–

在組件中也將組件中的服務注入到視圖容器參考中(在我的代碼中this.viewContainerReference下面,這是必須注入動態組件的地方)

componentReference = this.dynamicComponentService.append(ComponentClass, this.viewContainerReference);
componentReference.instance.someProp = whatever;

上面的someProp是組件的公共屬性,您可以將一些數據傳遞給它。

您可以像往常一樣將模塊作為@NgModule導入和組件的一部分導入,還請確保您具有以下模式:[NO_ERRORS_SCHEMA]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM