http://code.angularjs.org/1.0.2/docs/api/ng.$rootScope.Scope#$broadcast
scope可以以类似于DOM事件的方式进行事件传播。事件可以被broadcast(http://code.angularjs.org/1.0.2/docs/api/ng.$rootScope.Scope#$broadcast)到child scope或者emit(http://code.angularjs.org/1.0.2/docs/api/ng.$rootScope.Scope#$emit)到parent scope中。(当前scope如果有监听,也会执行)
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 35 36 37 38 39 40 | <!DOCTYPE HTML> <html lang= "zh-cn" ng-app> <head> <meta charset= "UTF-8" > <title>scope-event-propagation</title> <style type= "text/css" > .ng-cloak { display: none; } </style> </head> <body class= "ng-cloak" > <div ng-controller= "MyController" > root scope count:{ {count}} <ul> <li ng-repeat= "i in [1]" ng-controller= "MyController" > <button ng-click= "$emit('MyEvent')" >$emit( "MyEvent" )</button> <button ng-click= "$broadcast('MyEvent')" >$broadcast( "MyEvent" )</button> <br/> middle scope count:{ {count}} <ul> <li ng-repeat= "item in [1,2]" ng-controller= "MyController" > Leaf scope count:{ {count}} </li> </ul> </li> </ul> </div> <script src= "../angular-1.0.1.js" type= "text/javascript" ></script> <script type= "text/javascript" > function MyController($scope) { $scope.count = 0; $scope.$on( "MyEvent" , function () { $scope.count++; }); } </script> </body> </html> <br> |
七、Scope Life Cycle(scope生命周期)
浏览器正常的事件流中,当浏览器接收到事件后,它会执行一个相应的javascript回调。一旦回调函数执行完毕后,浏览器将会重绘DOM,并返回到继续等待事件的状态。
当浏览器在angular执行环境外调用javascript代码时,这意味着angular是不知道model的改变的。要正确处理model的修改,这个命令必须通过使$apply方法进入angular执行环境。只有在$apply方法中的model变更,才会正确地被angular统计。例如,一个directive监听了DOM事件,例如ng-click,它必须在$apply方法中对表达式进行求值。
在对表达式求值之后,$apply方法执行一个$digest。在$digest阶段里,scope检查所有$watch监听的表达式,将现在的值与旧的值作比较。脏检查(dirty checking)是异步的。这意味着赋值语句(例如$scope.username=”angular”)将不会马上导致一个$watch被通知,反而,$watch的通知将会延迟到$digest阶段。这个延迟是必须的,因为它把多个model更新联合到一个$watch通知中,这保证了在$watch通知的过程中,没有其他$watch在执行。如果一个$watch改变了model的值,那么它将会强制增加一个$digest周期。