J'utilise le code suivant pour créer les composants dynamiques
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">
});
}
}
}
Le composant dynamique est créé parfaitement et tout fonctionne comme prévu. Mais le seul problème est que je veux ajouter une classe pour composant dynamique afin qu'il puisse être
<dynamic-component class="dynamicClass">
Toute aide est appréciée :(
Hmm .. Je l'ajoute généralement à la selector
du composant qui est supposé être un entryComponent ...
selector: 'dynamic-component.someclass',
^^^^^^^^^^^
pour ajouter un attribut, utilisez le sélecteur d'attribut:
selector: 'dynamic-component[myattr=value]',
Je l'appelle fonctionnalité cachée de entryComponents
mais son approche déclarative et ne peut pas être changée à l'exécution (en effet on peut le changer)
Les opérations DOM de haut niveau sont effectuées avec le fournisseur Renderer2
. Considérant qu'il a été injecté, c'est:
this.renderer2.addClass(compRef.location.elementRef, 'dynamicClass');
Il convient de noter que selon la manière dont l'élément dynamique est attaché à DOM, cela peut être une complication inutile.
Considérant que dynamicComponentContainer
est un élément DOM réel et non pas <ng-template>
, la vue du composant dynamique peut être directement montée sur le conteneur, éliminant ainsi l'élément <dynamic-component>
wrapper
Étant donné le conteneur:
<div class="dynamicClass" #dynamicComponentContainer></div>
Ce sera:
var compRef = componentFactory.create(
this.injector,
[],
this.dynamicComponentContainer.element.nativeElement
);
Dans Angular 5/6, en utilisant Renderer2 à partir de @ angular/core, vous pouvez faire quelque chose comme ci-dessous:
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');
});
}