• AngularJS中的事件


    欢迎大家指导与讨论 : )

      前言

       Angular的作用域在本质上是分层次的(有的住户在低层, 有的住户在高层), 它们可以通过父子关系很自然地进行沟通。但通常, 这种沟通是单向的(父->子的单向沟通), 并且它们的作用域不共享变量, 它们的执行功能往往也各不相同, 也与它们父树上的位置无关。因此,在这种情况下,我们可以通过在这个链上传递事件的方式在作用域之间通讯(住在第n层的居委会主席对他的手下说: '嘿! 哥们! 麻烦帮我逐层告诉这栋楼的楼上/楼下的住户, 他们该交电费啦!')。注意, 受作用的只有某条链(隔壁楼的住户可不会听你的话哦)

      彩蛋——父子作用域间共享变量

      如果才能令父子作用域间可共享变量呢?(不单是父->子的方向, 还有子->父的方向)。答案是, 让子作用域"继承"父作用域$scope对象上的某一对象。

        <div ng-controller="parent">
            父:{{ model.test }}
            <button ng-click="change1();">点我by父亲</button>
            <div ng-controller="child">
                子:{{ model.test }}
                <button ng-click="change2();">点我by儿子</button>
            </div>
        </div> 

     

        app.controller('parent', ['$scope', function($scope){
            $scope.model = {};
            $scope.model.test = '父亲';
            $scope.change1 = function(){
                $scope.model.test = '父亲导致的改变';
            }
        }]);
        app.controller('child', ['$scope', function($scope){
            $scope.change2 = function(){
                $scope.model.test = '儿子导致的改变';
            }
        }])

      通讯——在链上传递事件

      下面的这个例子可以说明, 在一个"根"作用域下, 设置了两条"链"(两栋楼)。 实验可见: 楼A的事件传递, 不会被楼B的住户所接受:事件传递是在单链上的。但每条链的链头必定是$rootScope作用域

    <body ng-controller="rootController">
        <div ng-controller="leftParent">
            <div ng-controller="SelfCtrl">
                <a ng-click="click();">点我</a>
                <div ng-controller="ChildCtrl"></div>
            </div>
            <div ng-controller="BroCtrl"></div>
        </div>
        <div ng-controller="rightParent">
            
        </div>
    </body>

     

        app.controller('rootController', ['$scope', function($scope){
            
        }]);
        app.controller('leftParent', ['$scope', function($scope){
            $scope.$on('to-parent', function(d,data) {  
                console.log(data);         //父级能得到值  
            });  
            $scope.$on('to-child', function(d,data) {  
                console.log(data);         //子级得不到值  
            });        
        }]);
        app.controller('SelfCtrl', ['$scope', function($scope){
            $scope.click = function(){
                $scope.$broadcast('to-child', 'child');
                $scope.$emit('to-parent', 'parent');
            }
        }]);
        app.controller('ChildCtrl', ['$scope', function($scope){
            $scope.$on('to-child', function(d,data) {  
                console.log(data);         //子级能得到值  
            });  
            $scope.$on('to-parent', function(d,data) {  
                console.log(data);         //父级得不到值  
            });        
        }]);
        app.controller('BroCtrl', ['$scope', function($scope){
            $scope.$on('to-parent', function(d,data) {  
                console.log(data);        //平级得不到值  
            });  
            $scope.$on('to-child', function(d,data) {  
                console.log(data);        //平级得不到值  
            });          
        }]);
    
        app.controller('rightParent', ['$scope', function($scope){
            $scope.$on('to-parent', function(d,data) {  
                console.log(data);         //其它链上不能获取事件  
            });  
            $scope.$on('to-child', function(d,data) {  
                console.log(data);         //其它链上不能获取事件
            });        
        }]);

      传递的方向——$broadcast和$emit

      一方面, 如果要提醒一个全局模块, 我们最终需要通知高层次的作用域(如$rootScope), 则需要把事件向上传递($emit)。另一方面, 如果是一个选项卡指令和它的子面板指令之间的通讯, 则把事件向下传递($broadcast)

        $broadcast(name, args){//...}  $emit(name, args)(//...) 其中, name是事件的名称, 而args是参数集合(可以把参数集合到某一$scope对象里, 再把该对象传出)

      事件监听——$on

      当住户知道今天该交水费的时候, 就会安排一个人在家呆着, 等待"收水费"(为某个特定名称的事件注册监听器)的同学来进行配合。要监听事件,我们可以使用$on方法

            $scope.$on('to-parent', function(event,data) {  
                console.log(data);        
            }); 

     

      其中, event是事件对象,它是事件监听函数的首位参数,它拥有以下几个属性

      1. targetScope(作用域对象) 这个属性是发送或者广播事件的作用域

      2. name 正在处理事件的名称

      3. currentScope 处理当前事件的作用域

      4. stopPropagation(函数) 阻止通过$emit的事件传播进一步往上冒泡

      5. preventDefault(函数) 书上原文是"告诉子作用域无需处理事件", 但实验发现存在问题, 不知道是不是我使用的方法不对。这里举一个阻止默认行为的例子

      例子——锚点的preventDefault

    app.directive('a', function() {
        return {
            restrict: 'E',
            link: function(scope, elem, attrs) {
                if(attrs.ngClick || attrs.href === '' || attrs.href === '#'){
                    elem.on('click', function(e){
                        e.preventDefault();
                    });
                }
            }
       };
    });

      6. defaultPrevented(布尔值) 调用preventDefault()会把defaultPrevented设置为true

      事件相关的核心服务

      $emitted事件

    $scope.$on('$includeContentLoaded', function(evt){//...})

      1. $includeContentLoaded 该事件在ngInclude的内容重新加载时从ngInclude指令上发出

      2.  $includeContentRequested 每次ngInclude的内容被请求是,它都会被发送

      3.  $viewContentLoaded ngView内容被重新加载时,在当前ngView作用域上发送

      $broadcast事件

      1. $locationChangeStart (注: 事件的触发应该是先location后route事件)

      2. $locationChangeSuccess

      3. $routeChangeStart

      4. $routeChangeSuccess

      5. $routeChangeError

      6. $routeUpdate

      7. $destroy

     

      

      资料参考

       《AngularJS权威指南》P287

  • 相关阅读:
    8088汇编跳转和PSW状态字寄存器
    Delphi的函数指针
    服务器系统及软件常见漏洞
    TGraphiControl响应WM_MOUSEMOVE的过程(以TPaintBox为例)good
    两个奇怪的取地址符号
    把x指针指向的4个字节次序颠倒过来
    DELPHI中的消息处理机制(三种消息处理方法的比较,如何截断消息)
    探索C++的底层机制
    setprecision、fixed、showpoint的用法总结(经典!!超经典!!)
    段寄存器和8种地址寻址方式
  • 原文地址:https://www.cnblogs.com/BestMePeng/p/AngularJS_Event.html
Copyright © 2020-2023  润新知