Angular 2+从标记注入动态模板创建ViewRef

时间:2017-05-25 18:25:13

标签: javascript angular dynamic

我想从标记中创建一个动态插入到模板中的ViewRef。这可能基于以下代码示例吗?

template.html

<ng-container *ngTemplateOutlet="dynamic; context: cntx"></ng-container>
<ng-template #dynamic>
  <div [innerHTML]="markup"></div>
</ng-template>

从API调用中注入标记以绑定到div的innerHTML属性:

<div>
    <div id="forViewRef"></div>
</div>

component.ts

@ContentChild('#forViewRef', { read: ViewContainerRef }): someHndl;
private _nativeElem: any;

constructor(
    private sanitizer: DomSanitizer, 
    private _vcRef: ViewContainerRef, 
    private _resolver: ComponentFactoryResolver) {
    // to ensure template has been created, #dynamic
    this._nativeElem = this._vcRef.element.nativeElement;
}

// listen to lifecycle hook
ngAfterContentChecked() {
    if (this._nativeElem !== undefined)
        // childContent ref is undefined
        console.log(this.someHndl);
        // markup is in the DOM
        console.log(this._nativeElem.querySelectorAll('#forViewRef'));
}

1 个答案:

答案 0 :(得分:3)

要在<div id="forViewRef"></div>内动态创建组件,您可以执行以下操作:

假设我们需要加载以下组件

@Component({
  selector: 'dynamic-comp',
  template: `
   <h2>Dynamic component</h2>
    <button (click)="counter = counter + 1">+</button> {{ counter }}
  `
})
export class DynamicComponent {
  counter = 1;
}

首先将其添加到declarations

entryComponents@NgModule数组中
  ...
  declarations: [ ..., DynamicComponent ],
  entryComponents: [ DynamicComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

之后创建

<强> template.html

<button (click)="createComponent()">Create component</button>

<div id="forViewRef"></div>

最后写

<强> component.ts

export class AppComponent {
  compRef: ComponentRef<DynamicComponent>;

  constructor(private injector: Injector,
              private resolver: ComponentFactoryResolver,
              private appRef: ApplicationRef) {}


  createComponent() {
    const compFactory = this.resolver.resolveComponentFactory(DynamicComponent);
    this.compRef = compFactory.create(this.injector, null, '#forViewRef');

    this.appRef.attachView(this.compRef.hostView);
  }

  ngOnDestroy() {
    if(this.compRef) {
      this.compRef.destroy();
    }
  }
}

我使用appRef.attachView来包含动态组件以更改检测周期

<强> Plunker Example

另见