我正在按照其中一个指南来添加动态组件。 我在这些指南中看到的唯一区别是我从选择器启动动态组件(而不是像点击事件那样的事件),还有角度版本(在我的情况下为2.4.8)
我尝试过的事情:
但我还没弄清楚要做什么,而且我开始认为这可能与我使用的角度版本有关。有什么想法吗?
错误:
引起:找不到OneColumnSection的组件工厂。你是否 将它添加到@ NgModule.entryComponents?
home.html中的选择器
<sr-dynamic-section-component [componentData]="{'component': 'OneColumnSection', 'inputs': {'showNum': 2}}"></sr-dynamic-section-component>
动态部分Component.ts 我已经在那里添加了一些console.logs,除了工厂之后的那个,它们正在登录。
import {
Component,
Input,
ViewContainerRef,
ViewChild,
ReflectiveInjector,
ComponentFactoryResolver
} from "@angular/core";
import {OneColumnSection} from "./one-column.component";
@Component({
selector: 'sr-dynamic-section-component',
entryComponents: [OneColumnSection],
template: `
<div #dynamicSectionComponentContainer></div>
`,
})
export class DynamicSectionComponent {
currentComponent:any = null;
@ViewChild('dynamicSectionComponentContainer', {read: ViewContainerRef}) dynamicSectionComponentContainer: ViewContainerRef;
// component: Class for the component you want to create
// inputs: An object with key/value pairs mapped to input name/input value
@Input() set componentData(data: {component: any, inputs: any }) {
if (!data) {
return;
}
console.log("Component:" + data.component);
console.log("Inputs:" + JSON.stringify(data.inputs));
// Inputs need to be in the following format to be resolved properly
let inputProviders = Object.keys(data.inputs).map((inputName) => {
return {provide: inputName, useValue: data.inputs[inputName]};
});
let resolvedInputs = ReflectiveInjector.resolve(inputProviders);
// We create an injector out of the data we want to pass down and this components injector
let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicSectionComponentContainer.parentInjector);
console.log("about to factory:");
// We create a factory out of the component we want to create
let factory = this.resolver.resolveComponentFactory(data.component);
console.log("factory:" + factory);
// We create the component using the factory and the injector
let component:any = factory.create(injector);
// We insert the component into the dom container
this.dynamicSectionComponentContainer.insert(component.hostView);
// We can destroy the old component is we like by calling destroy
if (this.currentComponent) {
this.currentComponent.destroy();
}
this.currentComponent = component;
}
constructor(private resolver: ComponentFactoryResolver) {
}
}
OneColumnSection.ts
import {Component, Injector} from '@angular/core';
@Component({
selector: 'sr-one-column-section',
template: `
<div>Hello World One Column{{showNum}}</div>
`,
})
export class OneColumnSection {
showNum = 0;
constructor(private injector: Injector) {
this.showNum = this.injector.get('showNum');
}
}
HomeModule.ts
import {NgModule} from "@angular/core";
import {HomeComponent} from "./home.component";
import {HomeRoutingModule} from "./home-routing.module";
import {DynamicSectionComponent} from "./dynamic-section.component";
import {OneColumnSection} from "./one-column.component";
@NgModule({
imports: [HomeRoutingModule],
declarations: [HomeComponent,DynamicSectionComponent,OneColumnSection],
entryComponents: [OneColumnSection],
exports: [HomeComponent],
providers: []
})
export class HomeModule { }
在主文件夹中添加文件列表。
答案 0 :(得分:0)
如果我改变
let factory = this.resolver.resolveComponentFactory(data.component);
通过
let factory = this.resolver.resolveComponentFactory(OneColumnSection);
这是有效的,所以问题是选择器将OneColumnComponent作为字符串发送,我没有意识到,因为我正在记录输入,并且我看到OneColumnSection正确传递。 我只需要弄清楚将该参数传递给组件的最佳方法。
非常感谢!