在Angular 4中动态创建组件,您可以使用ngComponentOutlet
指令:https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html
类似的东西:
动态组件
@Component({
selector: 'dynamic-component',
template: `
Dynamic component
`
})
export class DynamicComponent {
@Input() info: any;
}
应用
@Component({
selector: 'my-app',
template: `
App<br>
<ng-container *ngComponentOutlet="component"></ng-container>
`
})
export class AppComponent {
this.component=DynamicComponent;
}
如何在此模板@Input() info: any;
中传递<ng-container *ngComponentOutlet="component"></ng-container>
个信息?
答案 0 :(得分:8)
在ngComponentOutlet
的拉取请求中讨论了这样的功能,但暂时放弃了。
即使https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html中当前显示的componentRef
也不公开,因此无法使用https://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L78
我建议您创建自己的指令,该指令派生自https://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L72
并为Angular 2 dynamic tabs with user-click chosen components
中显示的输入分配值this.compRef.instance.someProperty = 'someValue';
答案 1 :(得分:7)
在@GünterZöchbauer的帖子的帮助下,我用这种方式解决了类似的问题 - 我希望你能以某种方式适应它。
首先我定义了一些接口:
// all dynamically loaded components should implement this guy
export interface IDynamicComponent { Context: object; }
// data from parent to dynLoadedComponent
export interface IDynamicComponentData {
component: any;
context?: object;
caller?: any;
}
然后我在动态加载的组件
中实现了它们<强> dynamicLoadedComponentA.ts 强>
// ...
export class DynamicLoadedComponentA implements IDynamicComponent {
// ...
// data from parent
public Context: object;
// ...
之后我构建了一个负责魔术的新组件。这里重要的是我必须注册所有dyn。将组件加载为entryComponents。
<强> dynamic.component.ts 强>
@Component({
selector: 'ngc-dynamic-component',
template: ´<ng-template #dynamicContainer></ng-template>´,
entryComponents: [ DynamicLoadedComponentA ]
})
export class DynamicComponent implements OnInit, OnDestroy, OnChanges {
@ViewChild('dynamicContainer', { read: ViewContainerRef }) public dynamicContainer: ViewContainerRef;
@Input() public componentData: IDynamicComponentData;
private componentRef: ComponentRef<any>;
private componentInstance: IDynamicComponent;
constructor(private resolver: ComponentFactoryResolver) { }
public ngOnInit() {
this.createComponent();
}
public ngOnChanges(changes: SimpleChanges) {
if (changes['componentData']) {
this.createComponent();
}
}
public ngOnDestroy() {
if (this.componentInstance) {
this.componentInstance = null;
}
if (this.componentRef) {
this.componentRef.destroy();
}
}
private createComponent() {
this.dynamicContainer.clear();
if (this.componentData && this.componentData.component) {
const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory(this.componentData.component);
this.componentRef = this.dynamicContainer.createComponent(factory);
this.componentInstance = this.componentRef.instance as IDynamicComponent;
// fill context data
Object.assign(this.componentInstance.Context, this.componentData.context || {});
// register output events
// this.componentRef.instance.outputTrigger.subscribe(event => console.log(event));
}
}
}
这里使用了这个闪亮的新东西:
<强> app.html 强>
<!-- [...] -->
<div>
<ngc-dynamic-component [componentData]="_settingsData"></ngc-dynamic-component>
</div>
<!-- [...] -->
<强> app.ts 强>
// ...
private _settingsData: IDynamicComponent = {
component: DynamicLoadedComponentA,
context: { SomeValue: 42 },
caller: this
};
// ...
答案 2 :(得分:5)
I think for now you can use
https://www.npmjs.com/package/ng-dynamic-component
It is made specifically for this issue