Javascript 角度4+;为动态创建的ngComponentOutlet组件分配@Input
在Angular 4中,要动态创建组件,可以使用Javascript 角度4+;为动态创建的ngComponentOutlet组件分配@Input,javascript,angular,typescript,Javascript,Angular,Typescript,在Angular 4中,要动态创建组件,可以使用ngComponentOutlet指令: 大概是这样的: 动态分量 @Component({ selector: 'dynamic-component', template: ` Dynamic component ` }) export class DynamicComponent { @Input() info: any; } 应用程序 @组件({ 选择器:“我的应用程序”, 模板:` 应用程序 ` }) 导出类Ap
ngComponentOutlet
指令:
大概是这样的:
动态分量
@Component({
selector: 'dynamic-component',
template: `
Dynamic component
`
})
export class DynamicComponent {
@Input() info: any;
}
应用程序
@组件({
选择器:“我的应用程序”,
模板:`
应用程序
`
})
导出类AppComponent{
this.component=DynamicComponent;
}
如何传递
@Input()信息:any代码>此模板中的信息
?在对ngComponentOutlet
的拉取请求中讨论了此类功能,但现在已删除。
即使是中当前显示的componentRef
也不是公共的,因此不可用
我建议您创建自己的指令,从
并为输入赋值,如中所示
在@Günter Zö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;
}
然后我在动态加载的组件中实现了它们
@Component({
selector: 'dynamic-component',
template: `
Dynamic component
`
})
export class DynamicComponent {
@Input() info: any;
}
动态加载组件a.ts
在那之后,我建立了一个新的组件,它负责魔术。重要的是,我必须注册所有dyn。作为entryComponents加载的组件
动态.component.ts
我想现在你可以用
它是专门针对这个问题制作的如何从模板向动态创建的组件发送信息?您是否使用@Input decorators或其他东西?这取决于什么信息、来自何处以及您所说的“来自模板”是什么意思。如果需要支持,您需要提供更多详细信息。@GünterZöchbauer我已经更新了问题。如果您需要更多信息,请告诉我,谢谢。在v4.0发布之前是否可能有不同的ngComponentOutlet?我的意思是有一些解决这个问题的办法?我不知道计划。结论是,支持输入对于第一个版本来说太复杂了,他们希望按原样发布,然后最终再次处理这个问题,但从那时起我就没有看到相关的讨论(这并不意味着什么,因为我没有太多时间去检查)@GünterZöchbauer所以,如果我使用ngComponentOutlet
动态调用组件,那么将模型
或数据
从当前模板/组件发送到动态组件的唯一方法是创建自定义指令或使用某种服务,对吗ngComponentOutlet
没有任何内置功能来通信两个组件:调用者和被调用者?甚至连ngComponentOutletInjector
?ngComponentOutletInjector
都不能通过定制的喷油器。如果您在使用ngComponentOutletContainer
的组件中添加一个提供者,您将在大多数用例中自动获得相同的结果。我认为他们计划支持在Angular4中传递一些上下文。不确定这是否已经降落。@GünterZöchbauer谢谢!我将尝试ngComponentOutletContainer
+提供程序
选项。我还将查看感谢链接。我的另一个选择是一个服务,它可以更新双方的模型,但我真的很倾向于把它作为最后一个选项。这个解决方案可以用于提前编译吗?目前,还没有用AOT进行测试,但我会在不久的将来尝试测试它,并补充我的文章。不过问题是针对ngComponentOutlet的。没有这个指令,代码就会变得太混乱。
// 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;
}
// ...
export class DynamicLoadedComponentA implements IDynamicComponent {
// ...
// data from parent
public Context: object;
// ...
@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));
}
}
}
<!-- [...] -->
<div>
<ngc-dynamic-component [componentData]="_settingsData"></ngc-dynamic-component>
</div>
<!-- [...] -->
// ...
private _settingsData: IDynamicComponent = {
component: DynamicLoadedComponentA,
context: { SomeValue: 42 },
caller: this
};
// ...