私はAngularを初めて使用するので、専門用語を間違えたらごめんなさい。コンポーネントでtemplateURL(html)を動的に使用しようとしています。Class関数は同じままですが、htmlはbinType
に応じて変わります
これは私のコンポーネントクラスのソースです
import { Component, OnInit, Input, Output, EventEmitter, AfterViewInit, ViewContainerRef, ViewChild, Compiler, Injector, NgModule, NgModuleRef } from '@angular/core';
declare var module: {
id: string;
}
@Component({
selector: 'app-cart-bin',
styleUrls: ['./cart-bin.component.css'],
template: `
<ng-template #dynamicTemplate></ng-template>
`
})
export class CartBinComponent implements AfterViewInit, OnInit {
@ViewChild('dynamicTemplate', {read: ViewContainerRef}) dynamicTemplate;
public cols = 3;
public rows = 3;
@Input() binType = "";
@Input() toteList = [];
@Output() callbackMethod = new EventEmitter<string>();
constructor(private _compiler: Compiler, private _injector: Injector, private _m: NgModuleRef<any>) { }
ngOnInit() {
console.log(this.binType);
}
ngAfterViewInit() {
let tmpObj;
console.log(tmpObj);
if ((this.binType) == "2") {
tmpObj = {
moduleId: module.id,
templateUrl : './cart-bin.component_02.html'
};
} else {
tmpObj = {
moduleId: module.id,
templateUrl : './cart-bin.component_01.html'
};
}
console.log(tmpObj);
const tmpCmp = Component(tmpObj)(class {});
const tmpModule = NgModule({declarations: [tmpCmp]})(class {});
this._compiler.compileModuleAndAllComponentsAsync(tmpModule).then((factories) => {
const f = factories.componentFactories[0];
const cmpRef = f.create(this._injector, [], null, this._m);
cmpRef.instance.name = 'dynamic';
this.dynamicTemplate.insert(cmpRef.hostView);
});
}
getToteBoxClass(toteData){
...
}
getToteIcon(toteData){
...
}
toteSaveClick(toteData){
...
}
}
これはコンパイルしていますが、テンプレートが解析しておらず、次のエラーが発生しています
ERROR Error: Template parse errors:
Can't bind to 'ngStyle' since it isn't a known property of 'div'.
HTMLは正しいです@Component TypeDecoratorの一部として直接使用しました
コンパイラーを使用して動的コンポーネントを作成することは、角度でかなり反パターンであるという事実に加えて、CommonModule
をNgModule宣言に追加することでエラーを修正できると思います。
NgModule({imports: [CommonModule], declarations: [tmpCmp]})
テンプレートで ngSwitchCase
を使用し、基本コンポーネントから継承するが異なるテンプレートを持つ2つのコンポーネントを作成し、binType
に応じて、いずれかのコンポーネントをレンダリングします。
テンプレート:
<ng-container [ngSwitch]="binType">
<cart-bin-1 *ngSwitchCase="1"></cart-bin-1>
<cart-bin-2 *ngSwitchCase="2"></cart-bin-2>
</ng-container>
ts:
export abstract class CartBin {
// some common cart bin logic here:
}
@Component({
selector: 'cart-bin-1',
templateUrl: './cart-bin.component_01.html'
})
export class CartBin1 extends CartBin {
}
@Component({
selector: 'cart-bin-2',
templateUrl: './cart-bin.component_02.html'
})
export class CartBin2 extends CartBin {
}
これを使用する利点は、AOTバンドルにコンパイラーが含まれなくなるため、アプリケーションがより小さく、より速くなることです。また、これははるかに良く見えます:)