$broadcast
と$emit
のパフォーマンスの違いがなくなったので、$scope.$emit
より$rootScope.$broadcast
を選ぶ理由はありますか?
彼らは違います、そうです。
$emit
はスコープ階層(上向き)に制限されています - あなたの設計に合うのであればこれは良いかもしれませんが、それは私にはかなり恣意的な制限のようです。
$rootScope.$broadcast
はすべてのものに渡って動作します イベントを監視するには を選択します。これは私の考えではより賢明な制限です。
私は何かが足りないのですか?
編集:
答えに答えて明確にするために、派遣の方向は私が後にする問題ではありません。 $scope.$emit
はイベントを上向きに、$scope.$broadcast
- は下向きにディスパッチします。しかし、意図したすべてのリスナーに到達するために常に$rootScope.$broadcast
を使用しないのはなぜですか?
tl; dr (このtl; drは @ sp00m からの回答です)
$emit
はイベントを上にディスパッチします...$broadcast
はイベントを下にディスパッチします
詳細説明
$rootScope.$emit
は他の$rootScope
リスナーにそれを捕らえるだけです。すべての$scope
にそれを取得させたくない場合、これは良いことです。主に高レベルのコミュニケーション。子供がそれらを聞くことができないように大人が部屋の中で互いに話していると考えてください。
$rootScope.$broadcast
は、ほとんどすべてのものにそれを聞かせる方法です。これは両親が夕食の準備ができていると叫んでいるので、家の中の誰もがそれを聞くことに相当します。
$scope.$emit
は、その$scope
とそのすべての親、そして$rootScope
にそのイベントを聞かせたいときです。これは自宅で両親に泣き言を言う子供です(ただし、他の子供たちが聞くことができる食料品店ではありません)。
$scope.$broadcast
は$scope
自身とその子供たちのためのものです。これは彼らの両親が聞くことができないようにぬいぐるみにささやく子供です。
$emit
はスコープの階層を通してイベント upwards を送りますが、$broadcast
はすべての子スコープにイベント downwards を送ります。
私は次のリンクから次の図を作りました: https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
ご覧のとおり、$rootScope.$broadcast
は$scope.$emit
よりもはるかに多くのリスナーにヒットしています。
また、$scope.$emit
のバブリング効果は取り消すことができますが、$rootScope.$broadcast
は取り消すことができません。
$ scope。$ emit:このメソッドはイベントを上方向(子から親へ)に振り分けます。
$ scope。$ broadcast:メソッドはイベントを(親から子への)下方向にすべての子コントローラに送ります。
$ scope。$ on:メソッドは何らかのイベントを監視するために登録します。そのイベントをリッスンしているすべてのコントローラは、ブロードキャスト通知を受け取るか、子 - 親階層のどこに収まるかに基づいて発信します。
$ emitイベントは、そのイベントをリッスンしているすべての$スコープによってキャンセルすることができます。
$ onは "stopPropagation"メソッドを提供します。このメソッドを呼び出すことで、イベントがそれ以上伝播しないようにすることができます。
プランカー: https://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/ /
兄弟スコープ(直接の親子階層にないスコープ)の場合、$ emitと$ broadcastは兄弟スコープと通信しません。
詳細については http://yogeshtutorials.blogspot.in/2015/12/event-based-communication-between-angularjs-controllers.html を参照してください。
@Eddieは、質問に対する完璧な回答をしています。しかし、Pub/Subのより効率的なアプローチの使用に注意を向けたいと思います。
これ 答えが示唆するように、
$ broadcast/$ onアプローチはすべてのスコープにブロードキャストするので(スコープ階層の一方向または両方向に)、あまり効率的ではありません。 Pub/Subアプローチはもっと直接的です。購読者だけがイベントを取得するため、システム内のすべての範囲でイベントを機能させるわけではありません。
angular-PubSub
angularモジュールを使うことができます。アプリの依存関係にPubSub
モジュールを追加したら、PubSub
サービスを使用してイベント/トピックを購読および購読解除できます。
簡単に購読できます。
// Subscribe to event
var sub = PubSub.subscribe('event-name', function(topic, data){
});
公開が簡単
PubSub.publish('event-name', {
prop1: value1,
prop2: value2
});
購読を中止するには、PubSub.unsubscribe(sub);
OR PubSub.unsubscribe('event-name');
を使用します。
_ note _ メモリリークを防ぐために登録解除することを忘れないでください。
例えば、あなたが状態を保持しているサービスを持っている状況ではどうでしょうか。そのサービスへの変更をプッシュし、ページ上の他のランダムな要素はそのような変更をどのように認識することができますか?最近この問題に取り組むのに苦労している
RxJS Extensions for Angular を使用してサービスを構築します。
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);
app.factory("DataService", function(rx) {
var subject = new rx.Subject();
var data = "Initial";
return {
set: function set(d){
data = d;
subject.onNext(d);
},
get: function get() {
return data;
},
subscribe: function (o) {
return subject.subscribe(o);
}
};
});
それから変更を購読してください。
app.controller('displayCtrl', function(DataService) {
var $ctrl = this;
$ctrl.data = DataService.get();
var subscription = DataService.subscribe(function onNext(d) {
$ctrl.data = d;
});
this.$onDestroy = function() {
subscription.dispose();
};
});
クライアントはDataService.subscribe
で変更を購読することができ、プロデューサーはDataService.set
で変更をプッシュすることができます。