AngularJs的$emit和$broadcast事件分析

目录

前言

  Angular的作用域在本质上是分层次的:它们可以通过父子关系很自然地来回沟通。但通常,作用域是不共享变量的,它们执行的功能往往各不相同,跟在父树上的位置无关。在这种情况下,我们可以通过在这个链上传递事件的方式在作用域之间通信。
  因为作用域是有层次的,所以我们可以在作用域链上传递事件。通常来说,选择要使用的事件传递方式,一个好的经验法则是:查看将要触发事件的作用域。如果要通知整个事件系统(允许任意作用域处理这个事件),就要往下广播。
  另一方面,如果要提醒一个全局模块,我们最终需要通知高层次的作用域(例如$rootScope),并且需要把事件向上传递。


$emit

作用

  要把事件沿着作用域链向上派送(从子作用域到父作用域),我们要使用$emit()函数。一个$emit()事件函数的调用中,事件从子作用域冒泡到父作用域。在产生事件的作用域之上的所有作用域都会收到这个事件的通知。
当想要跟应用的其他部分交流状态的变更时,我们使用$emit()。如果想要跟$rootScope通信,需要$emit()这个事件。

参数

1
scope.$emit('user:logged_in', scope.user);

$emit()方法带有两个参数。

  1. name(字符串)
    要发出的事件名称。
  2. args(集合)
    一个参数的集合,作为对象传递到事件监听器中。

示例

1
2
3
4
5
6
7
8
9
10
11
12
angular.module('portalApp').component('orderIndex', {
transclude : true,
controller : function($scope, $http, $window,orderIndexService,currentUserService) {
var ctrl = this;

this.$routerOnActivate = function(next,previous) {
$scope.$emit("ComponentChange", {path:["个人中心"],pageTitle:"我的订阅"});
... ...
}
... ...
templateUrl : '/component/xxx/yyy/index.html'
}

  以上例子是angular组件的写法,当该组件路由被激活后,自动执行一次向上传递事件,从而更新当前页面的面包屑导航组件(是一个全局公共组件)。


$broadcast

作用

  要把事件向下传递(从父作用域到子作用域),我们使用$broadcast()函数。在$broadcast()法上,每个注册了监听器的子作用域都会收到这个信息。事件传播到所
有的指令和当前作用域的间接作用域上,并且一路往下调用每个监听器。用了$broadcast()方法之后,就没法取消事件的发送了。

参数

$broadcast()方法自身带有两个参数。

  1. name(字符串)
    要发出的事件名称。
  2. args(集合)
    一个参数的集合,作为对象传递到事件监听器中。

    示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $scope.searchReport = function () {
    $scope.$broadcast('openTab', {
    title: "检索",
    name: "search-report",
    data: {"text": $scope.text},
    reBuild: true
    });
    ... ...
    };

  以上例子在系统入口js中,向下广播了一个openTab事件,从而在系统加载完成后一进入时就默认打开一个tab页。