$ rootScope. $ Broadcast so với $ scope. $ phát ra


349

Bây giờ rằng sự khác biệt về hiệu năng giữa $broadcast$emitđã được loại bỏ, là có lý do nào để thích $scope.$emitđể$rootScope.$broadcast ?

Họ khác nhau, vâng.

$emit được giới hạn trong hệ thống phân cấp phạm vi (trở lên) - điều này có thể tốt, nếu nó phù hợp với thiết kế của bạn, nhưng dường như đối với tôi là một hạn chế khá tùy tiện.

$rootScope.$broadcasthoạt động trên tất cả những gì chọn để lắng nghe sự kiện, đó là một hạn chế hợp lý hơn trong tâm trí của tôi.

Tui bỏ lỡ điều gì vậy?

BIÊN TẬP:

Để làm rõ để trả lời câu trả lời, hướng của công văn không phải là vấn đề tôi đang theo đuổi. $scope.$emitgửi sự kiện lên trên và $scope.$broadcast- xuống dưới. Nhưng tại sao không luôn luôn sử dụng $rootScope.$broadcastđể tiếp cận tất cả những người nghe dự định?


3
toddmotto.com/... có tất cả
Divya MV

Câu trả lời:


1155

tl; dr (tl; dr này là từ câu trả lời của @ sp00m bên dưới)

$emitgửi một sự kiện trở lên ... $broadcastgửi một sự kiện đi xuống

Giải thích chi tiết

$rootScope.$emitchỉ cho phép $rootScopengười nghe khác bắt nó. Điều này tốt khi bạn không muốn$scope có được nó. Chủ yếu là một giao tiếp cấp cao. Hãy nghĩ về nó khi người lớn nói chuyện với nhau trong một căn phòng để những đứa trẻ không thể nghe thấy chúng.

$rootScope.$broadcastlà một phương pháp cho phép khá nhiều thứ nghe thấy nó. Điều này sẽ tương đương với việc cha mẹ la hét rằng bữa tối đã sẵn sàng để mọi người trong nhà nghe thấy.

$scope.$emitlà khi bạn muốn điều đó $scopevà tất cả cha mẹ của nó và $rootScopenghe sự kiện này. Đây là một đứa trẻ than vãn với cha mẹ ở nhà (nhưng không phải ở cửa hàng tạp hóa nơi những đứa trẻ khác có thể nghe thấy).

$scope.$broadcastlà cho $scopechính nó và con cái của nó. Đây là một đứa trẻ thì thầm với thú nhồi bông của nó để bố mẹ chúng không nghe thấy.


3
@NewDev Lý do là vì thường bạn có sự lặp lại phạm vi trên trang. Nếu bạn có hai hoặc nhiều phạm vi đại diện cho các trường hợp dữ liệu khác nhau - ví dụ: danh sách các hồ sơ bệnh nhân trên một trang, mỗi phạm vi có phạm vi riêng - thì nó sẽ không hoạt động để phát từ gốc một sự kiện chỉ dành cho một trong những sự kiện đó phạm vi. Tránh $rootScopephát sóng khi có thể cho phép tái sử dụng tốt hơn.
Tim Rogers

4
Không có gì bạn nói là sai, nhưng một cách để khái quát hóa rằng $ emit đi xuống tài liệu đến phạm vi con và $ emit đi lên tài liệu đến phạm vi cha mẹ. Cả hai sẽ kích hoạt bất kỳ người nghe gắn liền với phạm vi hiện tại.
Eric

123
Ví dụ bạn sử dụng rất tuyệt!
Assaf

72
Ồ Ngay cả trẻ em cũng có thể hiểu điều này! Thật tuyệt vời :)
Navaneeth

3
Ví dụ hoàn hảo, thích lời giải thích
Robin-Hoodie

104

Họ không làm cùng một công việc: $emitgửi một sự kiện lên trên thông qua hệ thống phân cấp phạm vi, trong khi $broadcastgửi một sự kiện xuống tới tất cả các phạm vi con.


2
Vâng, tôi lưu ý rằng trong câu hỏi (có lẽ tôi có thể đã nói rõ về hướng của công văn). Nhưng tôi cũng lưu ý rằng đó là một hạn chế khá độc đoán. Nếu tôi có thể tiếp cận "người nghe" của mình, tại sao tôi không thể luôn làm điều này từ dưới lên $rootScope?
Dev mới

Bởi vì $ emit sẽ không ảnh hưởng đến phạm vi con hoặc anh chị em của phạm vi. Chúng chỉ ánh xạ tới các kiểu lan truyền sự kiện của javascript - chụp và tạo bọt. $ Broadcast được sử dụng để chụp và $ emit được sử dụng để tạo bọt. Hiện tại có một bài viết về quirksmode dường như cổ xưa giải thích sự khác biệt khá rõ: quirksmode.org/js/events_order.html
Alan L.

77

Tôi đã tạo đồ họa sau từ liên kết sau: https://toddmotto.com/all-about-angenses-emit-broadcast-on-publish-subscribeing/

Phạm vi, rootScope, phát ra, phát sóng

Như bạn có thể thấy, $rootScope.$broadcastđánh nhiều người nghe hơn $scope.$emit.

Ngoài ra, $scope.$emithiệu ứng sủi bọt có thể bị hủy, trong khi $rootScope.$broadcastkhông thể.


24
Tôi thấy rất nhiều mũi tên.
Mars Robertson

4
@MichalStefanow Tôi là người hâm mộ câu trả lời trực quan :)
Maria Ines Parnisari

@mparnisari :. $ phát sóng (tên, args) -. Broadcast một sự kiện xuống qua $ phạm vi của tất cả trẻ em sinh ra các $ (tên, args) - Emit một sự kiện lên hệ thống phân cấp $ phạm vi cho tất cả các bậc cha mẹ, trong đó có $ rootScope
CodeMan

19

nhập mô tả hình ảnh ở đây

$ scope. $ emit: Phương thức này gửi sự kiện theo hướng đi lên (từ con đến cha mẹ)

nhập mô tả hình ảnh ở đây $ scope. $ Broadcast: Phương thức gửi sự kiện theo hướng đi xuống (từ cha mẹ sang con) đến tất cả các bộ điều khiển con.

nhập mô tả hình ảnh ở đây $ scope. $ on: Phương thức đăng ký để nghe một số sự kiện. Tất cả các bộ điều khiển đang nghe sự kiện đó đều nhận được thông báo về việc phát hoặc phát dựa trên nơi mà các bộ điều khiển phù hợp với hệ thống phân cấp cha-con.

Sự kiện $ emit có thể bị hủy bởi bất kỳ ai trong phạm vi $ đang lắng nghe sự kiện.

$ On cung cấp phương thức "stopPropagation". Bằng cách gọi phương thức này, sự kiện có thể được ngừng truyền bá thêm.

Plunker: https://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/

Trong trường hợp phạm vi anh chị em (phạm vi không nằm trong hệ thống phân cấp cha-con trực tiếp) thì $ emit và $ Broadcast sẽ không giao tiếp với phạm vi anh chị em.

nhập mô tả hình ảnh ở đây

Để biết thêm chi tiết, vui lòng tham khảo http://yogeshtutorials.blogspot.in/2015/12/event-basing-c truyền thông-b between-angjjs-controlers.html


Liên kết đến một giải pháp được hoan nghênh, nhưng vui lòng đảm bảo câu trả lời của bạn hữu ích mà không cần đến nó: thêm ngữ cảnh xung quanh liên kết để người dùng của bạn sẽ có ý tưởng về nó là gì và tại sao lại có, sau đó trích dẫn phần có liên quan nhất của trang bạn ' liên kết lại trong trường hợp trang đích không có sẵn. Câu trả lời ít hơn một liên kết có thể bị xóa.
Baum mit Augen

Mục tiêu là để cung cấp plunker làm việc, tuy nhiên, tôi đã thêm mô tả thích hợp ở đây.
Yogesh

3

@Eddie đã đưa ra một câu trả lời hoàn hảo cho câu hỏi được hỏi. Nhưng tôi muốn thu hút sự chú ý bằng cách sử dụng cách tiếp cận hiệu quả hơn của Pub / Sub.

Như câu trả lời này cho thấy,

Cách tiếp cận $ Broadcast / $ về cách tiếp cận không hiệu quả khủng khiếp vì nó phát sóng tới tất cả các phạm vi (Hoặc theo một hướng hoặc cả hai hướng của phân cấp Phạm vi). Trong khi cách tiếp cận Pub / Sub trực tiếp hơn nhiều. Chỉ những người đăng ký mới có được các sự kiện, vì vậy nó sẽ không đến mọi phạm vi trong hệ thống để làm cho nó hoạt động.

bạn có thể sử dụng angular-PubSubmô-đun góc. Khi bạn thêm PubSubmô-đun vào phụ thuộc ứng dụng của mình, bạn có thể sử dụngPubSub dịch vụ để đăng ký và hủy đăng ký các sự kiện / chủ đề.

Dễ dàng đăng ký:

// Subscribe to event
var sub = PubSub.subscribe('event-name', function(topic, data){

});

Dễ dàng để xuất bản

PubSub.publish('event-name', {
    prop1: value1,
    prop2: value2
});

Để hủy đăng ký, sử dụng PubSub.unsubscribe(sub);HOẶC PubSub.unsubscribe('event-name');.

LƯU Ý Đừng quên hủy đăng ký để tránh rò rỉ bộ nhớ.


2

Sử dụng RxJS trong một dịch vụ

Chẳng hạn như trong tình huống bạn có một Dịch vụ đang giữ trạng thái như thế nào. Làm cách nào tôi có thể đẩy các thay đổi đối với Dịch vụ đó và các thành phần ngẫu nhiên khác trên trang nhận thức được sự thay đổi đó? Gần đây đang vật lộn với việc giải quyết vấn đề này

Xây dựng một dịch vụ với RxJS Tiện ích mở rộng cho 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);
      }
  };
});

Sau đó, chỉ cần đăng ký để thay đổi.

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

Khách hàng có thể đăng ký thay đổi DataService.subscribevà nhà sản xuất có thể đẩy các thay đổi vớiDataService.set .

Các DEMO trên PLNKR .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.