typescript angular 4+ 为 ngComponentOutlet 动态创建的组件分配 @Input
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42522633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
angular 4+ assign @Input for ngComponentOutlet dynamically created component
提问by Doua Beri
In Angular 4 to dynamically create a component you can use ngComponentOutlet
directive: https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html
在 Angular 4 中动态创建一个组件,你可以使用ngComponentOutlet
指令:https: //angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html
something like this:
像这样:
Dynamic component
动态组件
@Component({
selector: 'dynamic-component',
template: `
Dynamic component
`
})
export class DynamicComponent {
@Input() info: any;
}
App
应用程序
@Component({
selector: 'my-app',
template: `
App<br>
<ng-container *ngComponentOutlet="component"></ng-container>
`
})
export class AppComponent {
this.component=DynamicComponent;
}
How do I pass @Input() info: any;
information in this template <ng-container *ngComponentOutlet="component"></ng-container>
?
如何@Input() info: any;
在此模板中传递信息<ng-container *ngComponentOutlet="component"></ng-container>
?
回答by Günter Z?chbauer
Such a feature was discussed in the pull request for ngComponentOutlet
but was dropped for now.
Even the componentRef
shown currently in https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.htmlis not public and therefore not available https://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L78
这样的功能在拉取请求中讨论过,ngComponentOutlet
但现在被删除了。即使当前componentRef
显示在https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html也不是公开的,因此不可用https://github.com/angular/angular/blob /3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L78
I'd suggest you create your own directive derived from https://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L72
我建议您从https://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L72创建自己的指令
and assign values to inputs like shown in Angular 2 dynamic tabs with user-click chosen components
并使用用户单击选择的组件为Angular 2 动态选项卡中所示的输入分配值
this.compRef.instance.someProperty = 'someValue';
回答by tobias-kutter
With the help of the post of @Günter Z?chbauer I solved a similar problem this way - I hope you can adapt it somehow.
在@Günter Z?chbauer 的帖子的帮助下,我以这种方式解决了一个类似的问题——我希望你能以某种方式适应它。
First I defined some interfaces:
首先我定义了一些接口:
// 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;
}
then I implemented them inside of the dynamically loaded component
然后我在动态加载的组件中实现了它们
dynamicLoadedComponentA.ts
动态加载组件A.ts
// ...
export class DynamicLoadedComponentA implements IDynamicComponent {
// ...
// data from parent
public Context: object;
// ...
After that I built a new component which is responsible for the magic. Important here is that I had to register all dyn. loaded components as entryComponents.
之后,我构建了一个负责魔法的新组件。这里重要的是我必须注册所有 dyn。加载组件作为 entryComponents。
dynamic.component.ts
动态组件.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));
}
}
}
here the usage of this shiny new stuff:
这里是这个闪亮的新东西的用法:
app.html
应用程序.html
<!-- [...] -->
<div>
<ngc-dynamic-component [componentData]="_settingsData"></ngc-dynamic-component>
</div>
<!-- [...] -->
app.ts
应用程序
// ...
private _settingsData: IDynamicComponent = {
component: DynamicLoadedComponentA,
context: { SomeValue: 42 },
caller: this
};
// ...
回答by Dany Y
I think for now you can use
我想现在你可以使用
https://www.npmjs.com/package/ng-dynamic-component
https://www.npmjs.com/package/ng-dynamic-component
It is made specifically for this issue
专门针对这个问题制作的