Qual é o uso adequado de um EventEmitter?

Eu li perguntas como Access EventEmitter Service dentro do CustomHttp onde o usuário usa EventEmitter em seu serviço, mas ele foi sugerido neste comentário para não usá-lo e usar os Observables diretamente em seus serviços.

Eu também li essa questão em que a solução sugere passar o EventEmitter para o filho e assiná-lo.

Minha pergunta então é: Devo ou não devo assinar manualmente para um EventEmitter? Como devo usá-lo?

    Não, você não deve se inscrever manualmente.

    EventEmitter é uma abstração angular2 e seu único propósito é emitir events em componentes. Citando um comentário de Rob Wormald

    […] EventEmitter é realmente uma abstração angular, e deve ser usado apenas para emitir events personalizados em componentes. Caso contrário, basta usar o Rx como se fosse qualquer outra biblioteca.

    Isto é declarado realmente claro na documentação do EventEmitter.

    Use por diretivas e componentes para emitir events personalizados.

    O que há de errado em usá-lo?

    Angular2 nunca nos garantirá que EventEmitter continuará sendo um Observable. Isso significa refatorar nosso código se ele mudar. A única API que devemos acessar é o método emit() . Nunca devemos nos inscrever manualmente em um EventEmitter.

    Todos os itens acima são mais claros neste comentário de Ward Bell (recomendado para ler o artigo, e a resposta para esse comentário). Citando para referência

    NÃO conte com EventEmitter continuando a ser um Observable!

    NÃO conte com os operadores Observable estando lá no futuro!

    Estes serão obsoletos em breve e, provavelmente, serão removidos antes do lançamento.

    Use EventEmitter apenas para binding de evento entre um componente filho e pai. Não se inscreva. Não chame nenhum desses methods. Apenas chame eve.emit()

    Seu comentário está de acordo com o comentário de Rob há muito tempo.

    Então, como usá-lo corretamente?

    Basta usá-lo para emitir events do seu componente. Dê uma olhada no exemplo a seguir.

     @Component({ selector : 'child', template : `  ` }) class Child { @Output() notifyParent: EventEmitter = new EventEmitter(); sendNotification() { this.notifyParent.emit('Some value to send to the parent'); } } @Component({ selector : 'parent', template : `  ` }) class Parent { getNotification(evt) { // Do something with the notification (evt) sent by the child! } } 

    Como não usá-lo?

     class MyService { @Output() myServiceEvent : EventEmitter = new EventEmitter(); } 

    Pare aí mesmo … você já está errado …

    Espero que esses dois exemplos simples possam esclarecer o uso adequado do EventEmitter.

    TL; Resposta DR :

    Não, não assine manualmente para eles, não os use em serviços. Use-os como mostrado na documentação apenas para emitir events em componentes. Não derrote a abstração angular.

    Sim, vá em frente e use.

    EventEmitter é um tipo público e documentado na API Angular Core final. Se é ou não baseado em Observable é irrelevante; Se os methods de emit e subscribe documentados forem adequados ao que você precisa, vá em frente e use-o.

    Como também afirmado nos documentos:

    Usa Rx.Observable, mas fornece um adaptador para que funcione conforme especificado aqui: https://github.com/jhusain/observable-spec

    Quando uma implementação de referência da especificação estiver disponível, mude para ela.

    Então, eles queriam um object Observable que se comportasse de uma certa maneira, eles o implementaram e o tornaram público. Se fosse apenas uma abstração Angular interna que não deveria ser usada, eles não a tornariam pública.

    Há várias ocasiões em que é útil ter um emissor que envia events de um tipo específico. Se esse é o seu caso de uso, vá em frente. Se / quando uma implementação de referência da especificação à qual eles se conectam estiver disponível, ela deverá ser uma substituição imediata, assim como qualquer outro polyfill.

    Apenas certifique-se de que o gerador que você passa para a function subscribe() siga as especificações vinculadas. O object retornado tem a garantia de ter um método de unsubscribe que deve ser chamado para liberar quaisquer referências ao gerador (este é atualmente um object de Subscription RxJs, mas que na verdade é um detalhe de implementação que não deve depender).

     export class MyServiceEvent { message: string; eventId: number; } export class MyService { public onChange: EventEmitter = new EventEmitter(); public doSomething(message: string) { // do something, then... this.onChange.emit({message: message, eventId: 42}); } } export class MyConsumer { private _serviceSubscription; constructor(private service: MyService) { this._serviceSubscription = this.service.onChange.subscribe({ next: (event: MyServiceEvent) => { console.log(`Received message #${event.eventId}: ${event.message}`); } }) } public consume() { // do some stuff, then later... this.cleanup(); } private cleanup() { this._serviceSubscription.unsubscribe(); } } 

    Todas as previsões sombrias e sombrias parecem resultar de um único comentário do Stack Overflow de um único desenvolvedor em uma versão de pré-lançamento do Angular 2.