路由的事件

事件这个词在前端出现的频率真是高,根本拦不住,哪都是.$route服务在路由过程中的每个阶段都会触发不同的事件,可以为这些不同的路由事件设置监听器并做出响应.

一共有4个事件用来监听路由的状态变化: $routeStartChange, $routeChangeSuccess, $routeChangeError, $routeUpdate.

其中最常用的是前两个,这里稍微解释一下.

(1) $routeStartChange

看名字就能猜出来它表示的是路由开始变化的事件,在浏览器地址栏发生变化之前AngularJS会先广播一下这个事件.路由会开始加载所有需要的依赖,模板和resolve部分的内容也会注入.

1
2
3
4
5
6
angular.module('myApp', [])
  .run(['$rootScope''$location'function($rootScope, $location){
    $rootScope.$on('$routeChangeStart'function(evt, next, current){
    console.log('route begin change');
  }); 
}]);

解释一下事件的参数,evt是事件对象,可以从中读取到一些route的信息.next是将要导航到的路由,current是当前的URL.

可以看见在这个时期我们可以做很多有用的事,因为此时仅仅是路由开始变化,对应的内容都还没来得及发生改变.这里我们可进行permission的校验,loading画面的加载,对应路由信息的读取等等.

(2) $routeChangeSuccess

在路由的所有依赖都被注入加载后,AngularJS会对外广播路由跳转成功的事件.

1
2
3
4
5
6
angular.module('myApp', [])
  .run(['$rootScope''$location'function($rootScope, $location) {
    $rootScope.$on('$routeChangeSuccess'function(evt, current, previous) {
      console.log('route have already changed');
    }); 
}])

这里也稍微解释下三个参数,evt是AngularJS事件对象,current是当前所处路由,previous是上一个路由.

剩下两个不太常用的事件,大家去看官方API说明吧,这里不介绍了

----------------------------------------------------------------------

  • $emit只能向parent controller传递event与data( $emit(name, args) )
  • $broadcast只能向child controller传递event与data( $broadcast(name, args) )
  • $on用于接收event与data( $on(name, listener) )
 

本节课程源码:

1
2
3
4
5
6
7
8
9
10
     
<div ng-controller="ParentCtrl">              <!--父级-->
  <div ng-controller="SelfCtrl">              <!--自己-->
    <a ng-click="click()">click me</a>
    <div ng-controller="ChildCtrl"></div>     <!--子级-->
  </div>
  <div ng-controller="BroCtrl"></div>         <!--平级-->
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var app = angular.module('myApp', []);
app.controller('SelfCtrl', function($scope) {
  $scope.click = function () {
    $scope.$broadcast('to-child', 'child');
    $scope.$emit('to-parent', 'parent');
  }
});
 
app.controller('ParentCtrl', function($scope) {
  $scope.$on('to-parent', function(event,data) {
    console.log('ParentCtrl', data);       //父级能得到值
  });
  $scope.$on('to-child', function(event,data) {
    console.log('ParentCtrl', data);       //子级得不到值
  });
});
 
app.controller('ChildCtrl', function($scope){
  $scope.$on('to-child', function(event,data) {
    console.log('ChildCtrl', data);      //子级能得到值
  });
  $scope.$on('to-parent', function(event,data) {
    console.log('ChildCtrl', data);      //父级得不到值
  });
});
 
app.controller('BroCtrl', function($scope){
  $scope.$on('to-parent', function(event,data) {
    console.log('BroCtrl', data);         //平级得不到值
  });
  $scope.$on('to-child', function(event,data) {
    console.log('BroCtrl', data);         //平级得不到值
  });
});

在$on的方法中的event事件参数,其对象的属性和方法如下

事件属性 目的
event.targetScope 发出或者传播原始事件的作用域
event.currentScope 目前正在处理的事件的作用域
event.name 事件名称
event.stopPropagation() 一个防止事件进一步传播(冒泡/捕获)的函数(这只适用于使用`$emit`发出的事件)
event.preventDefault() 这个方法实际上不会做什么事,但是会设置`defaultPrevented`为true。直到事件监听器的实现者采取行动之前它才会检查`defaultPrevented`的值。
event.defaultPrevented 如果调用了`preventDefault`则为true

----------------------------------------------------------

父传($scope.$broadcast)子接收($scope.$on)
angular.module('myApp', [])
.controller('ParentCtrl', ['$scope', function($scope) {
$scope.message = "Child updated from parent controller";

$scope.clickFunction = function() {
$scope.$broadcast('update_parent_controller', $scope.message);
};
}
])
.controller('ChildCtrl', ['$scope', function($scope) {
$scope.message = "Some text in child controller";

$scope.$on("update_parent_controller", function(event, message) {
$scope.message = message;
});
}
]);

Here a plunker for a live demo.

Instead, if it need to send data from the SecondController (child) to the FirstController (parent), it should use the $emit method.
Here the javascript code:
子传($scope.$emit)父接收($scope.$on)
angular.module('myApp', [])
.controller('ParentCtrl', ['$scope', function ($scope) {
$scope.message = "Some text in parent";
$scope.$on("update_parent_controller", function(event, message){
$scope.message = message;
});

}])
.controller('ChildCtrl', ['$scope', function ($scope) {
$scope.clickFunction = function() {
$scope.message = "Parent updated";

$scope.$emit('update_parent_controller', $scope.message);
}

}]);

Here a plunker for a live demo.

Finally, here a little trick where two controller have no parent/child relationship.
It should pass data from one controller through $rootScope and the $broadcast method.
Here the javascript code:
兄弟传($rootScope.$broadcast)兄弟接收($rootScope.$on)
angular.module('myApp', [])
.controller('FirstCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.message = "Clicked!";

$rootScope.clickFunction = function() {
$rootScope.$broadcast("Update", $scope.message);
};
}])
.controller('SecondCtrl', ['$scope','$rootScope', function($scope,$rootScope) {
$scope.message = "Waiting for a click...";

$rootScope.$on("Update", function(event, message) {
$scope.message = message;
});
}]);

Here a plunker for a live demo.

----------------------------------------------------------------------------------

发送消息: $scope.$emit(name, data) 或者 $scope.$broadcast(name, data);

接收消息: $scope.on(name,function(event,data){ });

区别: $emit 广播给父controller   $broadcast 广播给子controller

broadcast 是从发送者向他的子scope广播一个事件。

这里就是ParentController发送, ParentController 和 ChildController 会接受到, 而MainController是不会收到的

$emit 广播给父controller,父controller 是可以收到消息

$on 有两个参数function(event,msg)  第一个参数是事件对象,第二个参数是接收到消息信息

var app = angular.module('onBroadcastEvent', ['ng']);

app.controller('MainController', function($scope) {
$scope.$on('To-MainController', function(event,msg) {
console.log('MainController received:' + msg);
});
}); app.controller('ParentController', function($scope) {
$scope.click = function (msg) {
$scope.$emit('To-MainController',msg + ',from ParentController to MainController');
$scope.$broadcast('To-ChildController', msg + ',from ParentController to ChildController');
$scope.$broadcast('To-BrotherController', msg + ',from ParentController to BrotherController');
}
}); app.controller('ChildController', function($scope){
$scope.$on('To-ChildController', function(event,msg) {
console.log('ChildController received:' + msg);
});
}); app.controller('BrotherController', function($scope){
$scope.$on('To-BrotherController', function(event, msg) {
console.log('BrotherController received:' + msg);
});
});
 
 

angularJS 事件广播与接收[转]的更多相关文章

  1. AngularJS 事件广播与接收 $broadcast,$emit,$on 作用域间通信 封装factory服务 发布订阅

    不同作用域之间通过组合使用$broadcast,$emit,$on的事件广播机制来进行通信. 一.说明 1.广播 $broadcast 说明:将事件从父级作用域传播至本作用域及子级作用域. 格式:$b ...

  2. AngularJS 事件广播与接收 $emit $broadcast $on

    AngularJS中的作用域scope有一个非常有层次和嵌套分明的结构. 其中它们都有一个主要的$rootScope(也就说对应的Angular应用或者ng-app),然后其他所有的作用域部分都是继承 ...

  3. angularJS 事件广播与接收

    发送消息: $scope.$emit(name, data) 或者 $scope.$broadcast(name, data); 接收消息: $scope.on(name,function(event ...

  4. Angularjs中的事件广播 —全面解析$broadcast,$emit,$on

    Angularjs中不同作用域之间可以通过组合使用$broadcast,$emit,$on的事件广播机制来进行通信 介绍: $broadcast的作用是将事件从父级作用域传播至子级作用域,包括自己.格 ...

  5. node.js接收异步任务结果的两种方法----callback和事件广播

    事件广播 发送方调用emit方法,接收方调用on方法,无论发送方或是接收方,都会工作在一个频道 声明了一个模块,用于读取mime.json中的记录 var fs = require('fs'); va ...

  6. [spring源码学习]九、IOC源码-applicationEventMulticaster事件广播

    一.代码实例 回到第IOC的第七章context部分,我们看源码分析部分,可以看到在spring的bean加载之后的第二个重要的bean为applicationEventMulticaster,从字面 ...

  7. laravel 事件广播

    Laravel 5.1 之中新加入了事件广播的功能,作用是把服务器中触发的事件通过websocket服务通知客户端,也就是浏览器,客户端js根据接受到的事件,做出相应动作.本文会用简单的代码展示一个事 ...

  8. JS里关于事件的常被考察的知识点:事件流、事件广播、原生JS实现事件代理

    1.JS里面的事件流 DOM2级事件模型中规定了事件流的三个阶段:捕获阶段.目标阶段.冒泡阶段,低版本IE(IE8及以下版本)不支持捕获阶段 捕获事件流:Netscape提出的事件流,即事件由页面元素 ...

  9. Android的有序广播和无序广播(解决安卓8.0版本之后有序广播的接收问题)

    前言 Google从Android8.0版本开始,对在清单文件中静态注册广播做了限制. *** 特殊广播(动态注册广播接收者) 说:有序广播和无序广播之前,咱们先来说下Android中一些特殊的广播如 ...

随机推荐

  1. 【Devops】【docker】【CI/CD】docker启动的Jenkins容器 - 系统管理 - 全局工具配置 - 自动安装JDK、Maven、Git、Docker

    本篇适用于jenkins是启动的docker容器,自动安装JDK  Maven  Git   Docker等全局工具 ========================================= ...

  2. 使用 STHTTPRequest 框架解析 Soap1.2 教程

    1.STHTTPRequest框架地址 https://github.com/nst/STHTTPRequest 将 STHTTPRequest .h  STHTTPRequest.m 文件拖入工程中 ...

  3. svn各种箭头的含义

    黄色感叹号(有冲突):      有冲突了,冲突就是你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不允许 你提交,防止你的提交覆盖了 ...

  4. Java命令学习系列(七)——javap

    javap是jdk自带的一个工具,可以对代码反编译,也可以查看java编译器生成的字节码. 一般情况下,很少有人使用javap对class文件进行反编译,因为有很多成熟的反编译工具可以使用,比如jad ...

  5. Latex:多个公式使用同一个编号(右对齐)

    \usepackage{amsmath} \begin{equation}\begin{aligned}equation 1 ... \\equation 2 ... \\equation 3 ... ...

  6. Effective Java - Item 1: Consider static factory methods instead of constructors

    考虑使用静态工厂方法来替代构造方法, 这样的做的好处有四点. 1. 更好的表意 有的构造方法实际上有特殊的含义, 使用静态工厂方法能更好的表达出他的意思. 例如 BigInteger(int, int ...

  7. LCA算法总结

    LCA问题(Least Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找 ...

  8. ASP.NET MVC:无法向会话状态服务器发出会话状态请求

    ylbtech-Error-ASP.NET MVC: 无法向会话状态服务器发出会话状态请求 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Service (ASP.NET ...

  9. iOS:创建撒花动画

    一.介绍 在很多的游戏中,会有这么一个桥段,就是闯关成功后,会弹出一个奖品同时出现很多的鲜花或者笑脸.例如微信中祝福生日时,出现蛋糕等等.那么,这次我就来实现这个功能. 二.实现原理 对外接收一个图片 ...

  10. iOS开发-Launch Image和Launch Screen

    Launch Image是App的启动图片,LaunchScreen是iOS8之后的功能,两者都可以设置app的启动图片.iOS8之后官方的推荐了使用Launch screen.xib,在xib的中通 ...