如何在Angular中手动注册到内部组件事件?

时间:2017-04-23 07:15:00

标签: javascript angular rxjs

组件中,我有以下代码:

  <div class="app">
      <counter [init]="myValue" (change)="myValueChange($event);"></counter>
    </div>

通过模板注册(change)事件。

内部组件包含:

 @Output('change')counterChange = new EventEmitter();

发出(点击):

this.counterChange.emit(...)

问题:

在父组件中,如何通过代码而非模板注册(change)事件?

1 个答案:

答案 0 :(得分:1)

您应该通过将计数器子组件添加为Subject来订阅子组件中的ViewChild

重要:正如@echonax所提到的, EventEmitter永远不应该用于订阅,因为这个类最终可能只供内部使用而且不能保证是将来可以观察到更多详细信息,请参阅&{39; What is the proper use of an EventEmitter?&#39;。

使用SubjectSubscription(未经测试)的示例:

<强> app.component.ts

import {Component, AfterViewInit, OnDestroy, ViewChild} from '@angular/core';
import {CounterComponent} from './counter.component';
import {Subscription} from 'rxjs/Subscription';

@Component({
    selector: 'my-app',
    template: `
    <div class="app">
        <counter [value]="myValue"></counter>
    </div>`
})
export class AppComponent implements AfterViewInit, OnDestroy {

    @ViewChild(CounterComponent) counter: CounterComponent;

    public myValue = 2;

    private counterSubscription: Subscription;

    ngAfterViewInit() {
        this.counterSubscription = this.counter.subject.subscribe(
            value => console.log('value', value)
        );
    }

    ngOnDestroy() {
        if (!!this.counterSubscription) {
            this.counterSubscription.unsubscribe();
        }
    }
}

<强> counter.component.ts

import {Component, Input} from '@angular/core';
import {Subject} from 'rxjs/Subject';

@Component({
selector: 'counter',
template: `
    <div class="counter">
    <div class="counter__container">
        <button (click)="decrement();" class="counter__button">
        -
        </button>
        <input type="text" class="counter__input" [value]="value">
        <button (click)="increment();" class="counter__button">
        +
        </button>
    </div>
    </div>`
})
export class CounterComponent {

    @Input() value = 0;

    private _subject = new Subject<number>();

    public subject = _subject.asObservable();

    increment() {
        this.value++;
        this.subject.next(this.value);
    }

    decrement() {
        this.value--;
        this.subject.next(this.value);
    }
}