typescript 如何在动态创建的组件中使用输出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42022229/
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
How to use Output in dynamically created component
提问by Jerzy Gruszka
I am using this technique to dynamically create component:
我正在使用这种技术动态创建组件:
import {
Component, Input, ViewContainerRef, ViewChild, ReflectiveInjector, ComponentFactoryResolver,
Output, EventEmitter
} from '@angular/core';
@Component({
selector: 'dynamic-component',
template: `
<div #dynamicComponentContainer></div>
`,
})
export default class DynamicLayerComponent {
currentComponent = null;
@ViewChild('dynamicComponentContainer', { read: ViewContainerRef }) dynamicComponentContainer: ViewContainerRef;
@Output() visibility = new EventEmitter<boolean>();
// 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 }) {
console.log('setting');
if (!data) {
return;
}
// 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.dynamicComponentContainer.parentInjector);
// We create a factory out of the component we want to create
let factory = this.resolver.resolveComponentFactory(data.component);
// We create the component using the factory and the injector
let component = factory.create(injector);
// We insert the component into the dom container
this.dynamicComponentContainer.insert(component.hostView);
// We can destroy the old component is we like by calling destroy
if (this.currentComponent) {
console.log('fdsafa');
this.currentComponent.destroy();
}
this.currentComponent = component;
}
constructor(private resolver: ComponentFactoryResolver) {
console.log('dfsd');
}
}
And then I use it like that:
然后我像这样使用它:
<div *ngFor="let layer of sortedItems" class="single-layer">
<div>
<dynamic-component #DynamicLayer
[componentData]="{
component: layer.componentClass,
inputs: {
layerItem: layer,
sortFilter: sortFilter
}
}"
(visibility)="setLayerVisibility(layer, $event)">
</dynamic-component>
</div>
The problem is that I am not able to bind to an event, it does not work when binding to (visibility). The setLayerVisibility is not called when the event occurs. How to fix that problem ?
问题是我无法绑定到事件,绑定到(可见性)时它不起作用。事件发生时不会调用 setLayerVisibility。如何解决这个问题?
Of course my sample component based on componentClass has the @Output set like:
当然,我基于 componentClass 的示例组件的 @Output 设置如下:
@Output() visibility = new EventEmitter<boolean>();
private visibilityChanged() {
this.visibility.emit(this.layerItem.visible);
}
回答by mxii
Your factory:
您的工厂:
factory.create(injector);
will return an ComponentRef object, and with this object you can access that component itself.
将返回一个 ComponentRef 对象,您可以使用该对象访问该组件本身。
You could subscribe to that event via:
您可以通过以下方式订阅该事件:
component.instance.visibility.subscribe(v => ...);
回答by Aakash Purohit
Just subscribe the output event like this
只需像这样订阅输出事件
@ViewChild('yourComponentRef', { read: ViewContainerRef }) container: ViewContainerRef;
// Reference for dynamic component
private _ref;
constructor(
private _cfr: ComponentFactoryResolver){ }
public addDynamicComponent() {
const comp =
this._cfr.resolveComponentFactory(<YOUR_DYNAMIC_COMPONENT_HERE>);
this._ref = this.container.createComponent(comp);
// Input to dynamic component
this._ref.instance.inputVarHere = [1, 2, 3];
// Handles output event, just emit your output here
this._ref.instance.outputEventHere.subscribe(data => {
console.log(data);
});
}
public removeDynamicComponent() {
this._ref.destroy();
}
In your html file
在你的 html 文件中
<!-- Section to load dynamic component -->
<div #yourComponentRef></div>