動的コンポーネントを作成するために次のコードを使用しています
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">
});
}
}
}
動的コンポーネントは完璧に作成され、すべてが期待どおりに機能しています。しかし、唯一の問題は、動的コンポーネントのクラスを追加して、
<dynamic-component class="dynamicClass">
どんな助けでもありがたいです:(
うーん..私は通常、それをentryComponentであるはずのコンポーネントのselector
に追加します...
selector: 'dynamic-component.someclass',
^^^^^^^^^^^
属性を追加するには、属性セレクターを使用します。
selector: 'dynamic-component[myattr=value]',
entryComponentsの隠し機能と呼びます
しかし、その宣言的アプローチであり、実行時に変更することはできません(実際に変更できます)。
高レベルのDOM操作は、Renderer2
プロバイダーを使用して実行されます。注入されたことを考えると、次のようになります。
this.renderer2.addClass(compRef.location.elementRef, 'dynamicClass');
動的要素がDOMにどのようにアタッチされているかによっては、これは不要な複雑化である可能性があることに注意してください。
dynamicComponentContainer
は実際のDOM要素であり、<ng-template>
ではないことを考えると、動的コンポーネントのビューをコンテナに直接マウントできるため、<dynamic-component>
ラッパー要素を排除できます。
コンテナを考える:
<div class="dynamicClass" #dynamicComponentContainer></div>
そうなる:
var compRef = componentFactory.create(
this.injector,
[],
this.dynamicComponentContainer.element.nativeElement
);
Angular 5/6、@ angular/coreのRenderer2を使用すると、次のようなことができます。
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');
});
}