Reputation: 878
I am using the following code for creating the dynamic components
import {
Component, OnInit, ViewContainerRef, ViewChild, ViewChildren,
ReflectiveInjector, ComponentFactoryResolver, ViewEncapsulation, QueryList, Input, AfterViewInit
} from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { forEach } from '@angular/router/src/utils/collection';
import { IComponent } from 'app/app.icomponent';
@Component({
encapsulation: ViewEncapsulation.None,
selector: 'dynamic-component',
entryComponents: [HomeComponent, HighlevelSignalComponent],
template: `
<div #dynamicDiv [ngClass]="classFromMenu" >
<ng-template #dynamicComponentContainer></ng-template>
</div>
`,
styleUrls: [
'./dynamic-content.component.css'
],
})
export class DynamicComponent implements IComponent, OnInit, AfterViewInit {
classFromMenu: any;
@ViewChild('dynamicComponentContainer', { read: ViewContainerRef }) dynamicComponentContainer: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver, private route: Router,
private activatedRoute: ActivatedRoute, ) {
}
.......
buildComponent(passedData) {
// orderAndObjs has the data for creating the component
this.orderAndObjs.forEach(obj => {
var componentFactory = this.resolver.resolveComponentFactory(obj.component);
var compRef = this.dynamicComponentContainer.createComponent(componentFactory);
// compRef is the component that is created.
//Assuming the component that i am trying to create is <dynamic-component>.
//I want to add either a class or any other attribute like this
//<dynamic-component class="flex">
});
}
}
}
The dynamic-component is created perfectly fine and everything is working as expected. But the only issue is I want to add a class for dynamic-component so that it can be
<dynamic-component class="dynamicClass">
Any help is appreciated :(
Upvotes: 16
Views: 16002
Reputation: 222498
High-level DOM operations are performed with Renderer2
provider. Considering that it was injected, it is:
this.renderer2.addClass(compRef.location.nativeElement, 'dynamicClass');
It should be noticed that depending on how dynamic element is attached to DOM, this may be unnecessary complication.
Considering that dynamicComponentContainer
is real DOM element and not <ng-template>
, the view of dynamic component can be directly mounted to the container, thus eliminating <dynamic-component>
wrapper element:
Given the container:
<div class="dynamicClass" #dynamicComponentContainer></div>
It will be:
var compRef = componentFactory.create(
this.injector,
[],
this.dynamicComponentContainer.element.nativeElement
);
Upvotes: 7
Reputation: 1175
In Angular 5/6, using Renderer2 from @angular/core, you can do something like below:
constructor(private resolver: ComponentFactoryResolver, private route: Router,
private activatedRoute: ActivatedRoute, private renderer2: Renderer2) {
}
buildComponent(passedData) {
this.orderAndObjs.forEach(obj => {
var componentFactory = this.resolver.resolveComponentFactory(obj.component);
var compRef = this.dynamicComponentContainer.createComponent(componentFactory);
this.renderer2.addClass(compRef.location.nativeElement, 'flex');
});
}
Upvotes: 9
Reputation: 214067
Hmm.. I usually add it to the selector
of component that is supposed to be an entryComponent ...
selector: 'dynamic-component.someclass',
^^^^^^^^^^^
to add attribute use attribute selector:
selector: 'dynamic-component[myattr=value]',
I call it hidden feature of entryComponents
but its declarative approach and can't be changed at runtime(indeed we can change it)
Upvotes: 17