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

phi*_*yoo 12 angular

解决了Eric Martinez在Angular 2中的回答- 动态添加/删除组件,我想限制创建的组件数量.然后删除一个组件后,我试图将该事件发送给父组件,以便父级知道当前创建的组件数.

在这个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")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*nez 23

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

现在,话虽如此,你可以做的是创建一个你可以订阅的属性,我不会使用EventEmitter.

我的解决方案是使用Subject(因为我正在做一个我自己的小项目).

您的动态组件将如下所示

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

您正在加载动态组件的组件

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");
    });
});
Run Code Online (Sandbox Code Playgroud)

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

  • *Foster*组件:非常合适. (4认同)