Creating angular2 component with ng content dynamically

I would like to set the body of <ng-content> when instantiating a component dynamically using ComponentFactoryResolver .

I see that I can access input and output using ComponentRef , but not a way to set <ng-content> .

Please note <ng-content> I plan to customize, may contain plain text / may span dynamically generated components

 @Component({ selector: 'app-component-to-project', template: '<ng-content></ng-content>' }) export class ComponentToProject implements AfterContentInit { ngAfterContentInit() { // We will do something important with content here } } @Directive({ selector: 'appProjectionMarker' }) export class ProjectionMarkerDirective implements OnInit { constructor(private viewContainerRef: ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver) { } ngOnInit() { const componentFactory: ComponentFactory<ComponentToProject> = this.componentFactoryResolver.resolveComponentFactory(ComponentToProject); const componentRef: ComponentRef<ComponentToProject> = this.viewContainerRef.createComponent(componentFactory); // Question: How to set content before the child afterContentInit is invoked } } @Component({ selector: 'appTestComponent', template: '<div appProjectionMarker></div>' }) export class TestComponent {} 
+10
source share
1 answer

There is a projectableNodes parameter to the vcRef.createComponent method

 createComponent<C>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][], ngModule?: NgModuleRef<any>): ComponentRef<C>; 

You can use it to dynamically inject one component into another.

Let's say we have the following component

 @Component({ selector: 'card', template: ' <div class="card__top"> <h2>Creating a angular2 component with ng-content dynamically</h2> </div> <div class="card__body"> <ng-content></ng-content> </div> <div class="card__bottom"> <ng-content></ng-content> </div> ' }) export class CardComponent {} 

We want to create dynamically and insert some controls for its ng-content places. This can be done as follows:

 const bodyFactory = this.cfr.resolveComponentFactory(CardBodyComponent); const footerFactory = this.cfr.resolveComponentFactory(CardFooterComponent); let bodyRef = this.vcRef.createComponent(bodyFactory); let footerRef = this.vcRef.createComponent(footerFactory); const cardFactory = this.cfr.resolveComponentFactory(CardComponent); const cardRef = this.vcRef.createComponent( cardFactory, 0, undefined, [ [bodyRef.location.nativeElement], [footerRef.location.nativeElement] ] ); 

Plunger example

see also

+15
source

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


All Articles