下面是使用动态组件创建的StackBlitz上的两个MCVEs。我想知道为什么:
有谁有主意吗?
起作用的例子
app.component.ts
import { Component, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef, ViewChild, ViewContainerRef, Input, Compiler, Injector, NgModuleRef, SimpleChanges, NgModule, ComponentFactoryResolver, ReflectiveInjector } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { MatButtonModule } from '@angular/material';
@Component({
selector: 'my-app',
template: `
<ng-container
#viewContainerRef
></ng-container>
`,
})
export class AppComponent {
@ViewChild('viewContainerRef', { read: ViewContainerRef }) viewContainerRef: ViewContainerRef;
constructor(
private compiler: Compiler,
private injector: Injector,
private ngModuleRef: NgModuleRef<any>,
private changeDetectorRef: ChangeDetectorRef,
) {
}
ngOnInit() {
const template = `
<button
mat-button
[innerHTML]="'Click me!'"
>
</button>
`
this.viewContainerRef.clear();
const component = Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template
})(class { });
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
this.compiler.compileModuleAndAllComponentsAsync(ngModule).then((factories) => {
const factory = factories.componentFactories[0];
const componentRef = this.viewContainerRef.createComponent(
factory,
this.viewContainerRef.length,
this.injector,
[],
this.ngModuleRef
);
this.changeDetectorRef.detectChanges();
});
}
}app.module.ts
import { NgModule, CompilerFactory, COMPILER_OPTIONS, Compiler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { JitCompilerFactory } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
export function createCompiler(compilerFactory: CompilerFactory) {
return compilerFactory.createCompiler();
}
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [
{ provide: COMPILER_OPTIONS, useValue: {}, multi: true },
{ provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS] },
{ provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory] },
],
})
export class AppModule { }不起作用的示例
将MatButtonModule添加到动态模块的导入中:
app.component.ts
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
MatButtonModule,
],
entryComponents: [component],
declarations: [component]
})(class { });行为
没有错误,但是动态组件似乎没有被插入(至少它是不可见的)。
发布于 2018-11-11 11:42:07
其原因是,您总是从数组中获取第一个已编译的工厂。
const factory = factories.componentFactories[0];当您需要从组件中获取工厂时:
const factory = factories.componentFactories.find(x => x.componentType === component);https://stackoverflow.com/questions/53247787
复制相似问题