Angular 2+ Create ViewRef from markup embedded in a dynamic template

I would like to create a ViewRef from markup that is dynamically inserted into the template. Is this possible based on the following code example?

template.html

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

Introduced markup from an API call to bind to innerHTML div attribute:

<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'));
}
0
source share
1 answer

To dynamically create components inside <div id="forViewRef"></div>, you can do the following:

Say we need to load the next component

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

so first add it to the array declarationsand entryComponentsyour@NgModule

  ...
  declarations: [ ..., DynamicComponent ],
  entryComponents: [ DynamicComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

after that create

template.html

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

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

and finally write

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,

.

+2

Source: https://habr.com/ru/post/1677959/


All Articles