159

私はのような質問を読んだCustomHttp内のEventEmitterサービスにアクセスするユーザーが彼のサービスでEventEmitterを使用しているところですが、彼はこの中で提案されましたコメント直接彼のサービスでObservablesを使用することはできません。

私もこれを読んだ質問このソリューションでは、EventEmitterを子に渡してサブスクライブすることを提案しています。

私の質問は次のとおりです:私は、または私は手動でEventEmitterを購読してはいけませんか?私はそれをどのように使うべきですか?


  • 可能な複製委任:EventEmitterまたはObservable in Angular2 - Günter Zöchbauer
  • いつものように、Markさんからの丁寧な回答ですが、実際に彼は私がなぜ説明したのかを説明していません。私はそれを閉めることに反対していませんが、私は彼の意見を最初に欲しがります。 @MarkRajcokの考え? - Eric Martinez
  • 私はこれを開いたままにしておきたいと思います(私はここで人々を指摘しています - 私はちょっとここで指摘するために私の他の答えを編集しました!)。あなたの答えは良い情報を持っています。私は2つの質問タイトルを欲しがっています...もう1つは" EventEmitterの正しい使い方は何ですか? - Mark Rajcok
  • @MarkRajcok私はそのタイトルが好きですが、現在の回答には合わないので、後でそれを更新し、使用方法の例を追加し、それがより意味を成さないようにしましょう。ご意見ありがとうございます :) - Eric Martinez
  • @MarkRajcokさんが提案したように編集しました(y)、(タイトルをコピー&貼り付け、あなたにすべてのクレジットを貼り付けました)。 - Eric Martinez

2 답변


267

いいえ、あなたは手動でそれを購読するべきではありません。

持つEventEmitterangle2の抽象化であり、その唯一の目的はコンポーネントでイベントを発生させることです。引用するコメントRob Wormaldの

[...] EventEmitterは実際にはAngular抽象であり、コンポーネント内でカスタムイベントを発生させるためだけに使用する必要があります。それ以外の場合は、Rxを他のライブラリと同じように使用してください。

これは、EventEmitterのドキュメントではっきりと述べられています。

ディレクティブとコンポーネントがカスタムイベントを生成するために使用します。

それを使用すると何が問題になりますか?

Angular2は、EventEmitterがObservableであり続けることを決して保証しません。つまり、コードが変更された場合には、コードをリファクタリングすることを意味します。私たちがアクセスしなければならない唯一のAPIは、emit()方法。私たちは手動でEventEmitterに登録するべきではありません。

上記のすべては、このWard Bellのコメント(記事を読むことをお勧めします。回答そのコメントに)。参照のための引用

Observableであり続けているEventEmitterに数えてはいけません!

将来観察される観察可能なオペレータには数えないでください!

これらはすぐに廃止され、リリース前に削除される可能性があります。

EventEmitterは、子コンポーネントと親コンポーネント間のイベントバインディングにのみ使用してください。それを購読しないでください。これらのメソッドを呼び出さないでください。電話のみeve.emit()

彼のコメントは長い時間前にロブのコメントに沿っている。

だから、それを正しく使う方法は?

コンポーネントを使用してイベントを発生させるだけです。次の例を見てください。

@Component({
    selector : 'child',
    template : `
        <button (click)="sendNotification()">Notify my parent!</button>
    `
})
class Child {
    @Output() notifyParent: EventEmitter<any> = new EventEmitter();
    sendNotification() {
        this.notifyParent.emit('Some value to send to the parent');
    }
}

@Component({
    selector : 'parent',
    template : `
        <child (notifyParent)="getNotification($event)"></child>
    `
})
class Parent {
    getNotification(evt) {
        // Do something with the notification (evt) sent by the child!
    }
}

どのようにそれを使用しない?

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

そこに止まる...あなたはすでに間違っている...

うまくいけば、これらの2つの簡単な例は、EventEmitterの正しい使い方を明らかにするでしょう。

TL; DR答え:

いいえ、手動で登録しないでください。サービスで使用しないでください。ドキュメンテーションに示されているようにそれらを使用して、コンポーネントでイベントを発生させます。角度の抽象化を破らないでください。


  • どういう意味:directives : [Child]コンポーネント定義では?これはコンパイルされていないようで、Angular2のドキュメントに記述されています。 - themathmagician
  • @エリック:あなたの例でそれを使用しない方法は非常に明白です。理由はなぜですか?@ Output&#39;サービスのデコレータ? - trungk18
  • @themathmagician少しの研究の後、私は見つけたここにそのdirectivesキーワードは廃止されました。使用declarationsのキーワード@NgModule指示通りにここにまたはここに - cjsimon
  • Tobyの最新の回答に対するコメント?彼の答えは今日受け入れられるはずだと思います。 - Arjan
  • @Ericあなたがこの回答を書いたとき、あなたは書いています:「これはすぐに廃止され、リリース前に削除されているかもしれません。しかし、これは2年前に述べられました、そして今、私たちはangular6を持っています。この声明は今でも適用されますか?私はEventEmitterがまだsubscribe()メソッドを持っていることを公式の文書で見ているので、GoogleがRxjsの科目にEEを置くのを止めたいと思ったら、すでにやっていると思います。だから元の答えはまだ角度の現在の状態によく合っていると思いますか? - Nad G

53

はい、それを使用してください。

EventEmitter〜です公開型、文書型最終的なAngular Core APIではそれがベースであるかどうかObservable無関係です。文書化されている場合emitそしてsubscribeメソッドは必要なものに合っています。

ドキュメントにも述べられているように:

Rx.Observableを使用しますが、ここで指定されているように動作させるアダプタを提供します:https://github.com/jhusain/observable-spec

仕様のリファレンス実装が利用可能になったら、それに切り替えます。

彼らはObservable彼らは特定の方法で行動したようなオブジェクトを実装し、公開しました。それが単に使用すべきでない内角の抽象概念であった場合、それらを公開することはできませんでした。

特定のタイプのイベントを送信するエミッタを持つと便利なことはたくさんあります。それがあなたのユースケースであれば、それに行きましょう。それらがリンクする仕様のリファレンス実装が利用可能な場合、それは他のポリフィルと同様にドロップイン置換でなければなりません。

ジェネレータがあなたに渡すことを確認してくださいsubscribe()関数はリンクされた仕様に従います。返されるオブジェクトには、unsubscribeこのメソッドは、ジェネレータへの参照を解放するために呼び出される必要があります(これは現在、RxJsSubscriptionオブジェクトそれは実際に依存するべきではない実装の詳細です)。

export class MyServiceEvent {
    message: string;
    eventId: number;
}

export class MyService {
    public onChange: EventEmitter<MyServiceEvent> = new EventEmitter<MyServiceEvent>();

    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();
    }
}

強く言及された運命と暗闇の予測はすべて、プレリリース版のAngular 2の単一の開発者からの単一のStack Overflowコメントから生じるようです。


  • これは合理的なように聞こえます。結局のところ、サブスクライブはイベントエミッタのパブリックメソッドですか? - Shawson
  • OK、一般の方には無料でご利用いただけます。しかし、この例ではObservable上でEventEmitterを使用する実用的な理由はありますか? - Botis
  • Angular v6とEventEmmiterは非推奨または削除されていないため、使用することをお勧めします。しかし、RxJSからObservablesを使用する方法を学ぶことには利点があります。 - David Meza

リンクされた質問


最近の質問