如何在动态添加的组件上使用事件发射器?

Posted

技术标签:

【中文标题】如何在动态添加的组件上使用事件发射器?【英文标题】:How can I use an event emitter on a dynamically added component? 【发布时间】:2016-07-14 12:26:55 【问题描述】:

根据Angular 2 - Adding / Removing components on the fly 的 Eric Martinez 的回答,我想限制创建的组件数量。然后在删除一个组件后,我尝试将该事件发送给父级,以便父级知道当前创建的组件数量。

在这个Plunker 中,我将组件的数量限制为 4,然后我试图发出一个事件来降低该计数。事件没有发出。如何从动态添加的组件中发出事件?

// dynamic component
@Component(
    selector : 'dynamic',
    template : `
    <div>
        Component number _idx <button (click)="remove()">Remove</button>
    </div>`
)
class DynamicCmp 
    _ref: ComponentRef;
    _idx: number;
    @Output lowerIndex = new EventEmitter<any>();
    remove() 
        this._ref.dispose();
        this.lowerIndex.emit(true);
    


// Parent container component    
@Component(
    selector: 'my-app',
    template : `
        <button (click)="add()">Add new component</button>
        <div #location (lowerIndex)="lowerIndex();"></div>
    `
)
export class App 
    idx: number = 0;
    constructor(private _dcl: DynamicComponentLoader, private _e: ElementRef) 

    lowerIndex() 
        this.idx--;
        console.log("subtracted");
    

    add() 
        if (this.idx < 4) 
            this._dcl.loadIntoLocation(DynamicCmp, this._e, 'location').then((ref) => 
            ref.instance._ref = ref;
            ref.instance._idx = this.idx++;
            );

            console.log("added")
        
    

我在这里发布了组件,因为 *** 需要使用 plunker 链接发布的代码。代码与 plunker 中看到的完全相同

【问题讨论】:

【参考方案1】:

这里的问题是动态加载的组件与加载它们的组件没有父/子关系。这就是为什么要从动态加载的组件访问属性必须使用ref.instance.property。该组件没有与父组件一起编译,因此父组件对 foster 组件一无所知。

现在,话虽如此,您可以做的是创建一个可以订阅的属性,并为此提供I wouldn't use an EventEmitter。

我的解决方案是改用主题(就像我在自己的一个小项目中所做的那样)。

你的动态组件看起来像这样

class DynamicCmp 

    // Subject instead of an EventEmitter
    lowerIndex: Subject<boolean> = new Subject();

    remove() 
        // We send true, although in the example is not being used
        this.lowerIndex.next(true);

        // Remove the component from the view
        this._ref.dispose();
    

加载动态组件的组件

template : '<div #location></div>'; // Note that I removed (lowerIndex)="..."
this._dcl.loadIntoLocation(DynamicCmp, this._e, 'location').then((ref) => 
    //...

    // Subscribe to the Subject property
    ref.instance.lowerIndex.subscribe(v => 
        this.idx--;
        console.log("subtracted");
    );
);

这是您的 plnkr 工作并更新到 beta.12。

【讨论】:

太棒了!谢谢你的帮助埃里克:) Foster 组件:非常恰当。 很好的解决方案! 像魅力一样工作!我终有一天会成为发布这些答案的那种人;P

以上是关于如何在动态添加的组件上使用事件发射器?的主要内容,如果未能解决你的问题,请参考以下文章

Java:向动态创建的组件添加事件

Angular 表单:如何动态添加/删除子表单组件

在 Vue 中动态添加带有事件的不同组件

使用动态组件和自定义事件时的 VueJS 警告

IONIC 4 - 如何在 HTML 中动态添加点击事件

map组件的标记点上添加的单击事件名是啥