AnularJS1>>>事件

在Web应用的组件是松耦合的情况下,比如需要用户验证然后处理授权,即时的通信不总是可行的,因为组件没有耦合在一起。

例如,如果后端对一个请求返回了状态码401(表明一个未经授权的请求),我们期望Web应用不允许用户停留在当前视图,在这种情况下,我们希望应用把用户重定向到登录或者注册页面去。

基于这个逻辑,我们不能从外部告诉控制器设置一个新地址。我们也希望这个功能能覆盖多个作用域,这样可以用相同的行为来保护这些作用域。

我们需要另一种方式在它们之间通信。

AngularJS的作用域在本质上是分层次的:它们可以通过父子关系很自然地来回沟通。但通常,作用域是不共享变量的,它们执行的功能往往各不相同,跟在父树上的位置无关。

在这种情况下,我们可以通过在这个链上传递事件的方式在作用域之间通信。

什么是事件

如同浏览器相应浏览器层的事件,比如鼠标点击、页面滚动那样,Angular应用也可以响应Angular事件。这使我们可以在应用层中嵌套的各组件之间进行通信,即使这些组件在创建时并未考虑到其他组件。

注意,Angular事件系统并不与浏览器的事件系统相通,这意味着,我们只能在作用域上监听Angular事件而不是DOM事件。
我们可以认为,事件是在应用中传播的信息片段,通常(可选)包含了应用中发生的事情的信息。

事件传播

因为作用域是有层次的,所以我们可以在作用域链上传递事件。
通常说来,选择要使用的事件传递方式,一个好的经验法则是:查看将要触发事件的作用域。如果要通知整个事件系统(允许任意作用域处理这个事件),就要往下广播。
另一方面,如果要提醒一个全局模块(为了说),我们最终需要通知高层次的作用域(例如$rootScope),并且需要把事件向上传递。
比如,当我们在做路由的时候,“全局”应用状态需要知道应用当前设置了哪个页面。另一方面,如果我们是在一个选项卡指令和它的子面板指令之间通信,就需要把事件向下传。

使用$emit来冒泡事件

要把事件沿着作用域链向上派送(从子作用域到父作用域),我们要使用$emit()函数。

//发送一个事件
//当们的用户以当前user登录了
scope.$emit(‘user:logged_in’, scope.user);

在一个 e m i t ( ) 使 emit()事件函数的调用中,事件从子作用域冒泡到父作用域。在产生事件的作用域之上的所有作用域都会收到这个事件的通知。 当想要跟应用的其他部分交流状态的变更时,我们使用 emit()。如果想要跟 r o o t S c o p e rootScope通信,需要 emit()这个事件。
$emit()方法带有两个参数。
1.name(字符串)
要发出的事件名称。
2.args(集合)
一个参数的集合,作为对象传递到事件监听器中。
e m i t ( ) emit()方法返回了一个事件对象 从监听器中发出的一切异常都会传递到 exceptionHandler服务中。

使用$broadcast向下传递事件

要把事件向下传递(从父作用域到子作用域),我们使用$broadcast()函数。

//等等,购物车去结账了
//当购物车在结账的时候
//下面所有的指令都应当禁用自己
scope. b r o a d c a s t ( c a r t : c h e c k i n g o u t , s c o p e . c a r t ) ; broadcast('cart:checking_out',scope.cart); 在 broadcast()方法上,每个注册了监听器的子作用域都会收到这个信息。事件传播到所有的指令和当前作用域的间接作用域上,并且一路往下调用每个监听器。
用了$broadcast()方法之后,就设法取消事件的发送了。
$broadcast()方法自身带有两个参数。
1.name(字符串)
要发出的事件名称
2.args(集合)
一个参数的集合,作为对象传递到事件监听器中。
e m i t ( ) emit()方法返回了一个事件对象 从监听器中发出的一切异常都会传递到 exceptionHandler服务中。

事件监听

要监听一个事件,我们可以使用$on()方法。这个方法为具有某个特定名称的事件注册了一个监听器。事件名称就是在Angular中触发的事件类型。
例如,我们可以在路由变更过程被触发时,监听事件:

$scope.on('$routeChangeStart',
          function(evt, next, current){
                  //一个新的路由被触发了
});
不管什么时候事件$routeChangeStart被触发,监听器都会被调用。
Angular把evt对象作为第一个参数传给正在监听的一切事件,不管它是我们自定义的事件还是内置的Angular服务

事件对象

事件对象有以下属性。
1.targetScope(作用域对象)
这个属性是发送或者广播事件的作用域。
2.currentScope(作用域对象)
这个对象包含了当前处理事件的作用域
3.name(字符串)
这个字符串是触发之后,我们正在处理的事件名称。
4.stopPropagation(函数)
stopPropagation()函数取消通过$emit触发的事件的进一步传播。
5.preventDefault(函数)
preventDefault把defaultPrevented标志设置为true。尽管不能停止事件的传播,我们可以告诉子作用域无需处理这个事件
6.defaultPrevented(布尔值)
调用preventDefault()会把defaultPrevented设置为true。
$on()函数返回了一个反注册函数,我们可以调用它来取消监听器。

事件相关的核心服务

Angular核心框架发送事件,我们监听之后执行操作。可以用事件来让自己的Angular对象能在全局事件的不同状态上与应用交互。
我们用 e m i t ( ) emit()调用的有好几个事件,它们把事件往上发,更多调用的是 broadcast()事件。

核心系统的 e m i t t e d 使 emitted事件 下面的事件从指令向上发送到包含指令调用的作用域。我们可以使用 on()在这个链网上的任意作用域里监听这些方法:

$scope.$on('includeContentLoaded',
       function(evt){
 });
 1.$includeContentLoaded
 $includeContentLoaded事件当ngInclude的内容重新加载时,从ngInclude指令上触发。
 2.$includeContentRequested
 $indeludeContentRequested事件从diaoyongfngInclude的作用域上发送。每次ngInclude的内容被请求时,它都会被发送。
 3.$viewContentLoaded
 $viewContentLoaded事件每当ngView内容被重新加载时,从当前ngView作用域上发送.

核心系统的 b r o a d c a s t 1. broadcast事件 1. loacationChangeStart
当Angular从 l o a c a t i o n loacation服务对浏览器的的地址作更新时,会触发 locationChangeStart事件.
2. l o a c a t i o n C h a n g e S u c c e s s , loacationChangeSuccess 当且仅当浏览器的地址成功变更,又没有阻止 locationChangeStart事件的情况下, l o c a t i o n C h a n g e S u c c e s s locationChangeSuccess事件会从 rootScope事件会从 r o o t S c o p e 广 . 3. rootScope上广播出来. 3. routeChangeStart
在路由变更发生之前, r o u t e C h a n g e S t a r t routeChangeStart事件从 rootScope发送出来。也就是在路由服务器开始解析路由变更所需的所有依赖项时。

猜你喜欢

转载自blog.csdn.net/piano9425/article/details/84197245