zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Maidsafe-去中心化互联网白皮书
    The Top 20 Cybersecurity Startups To Watch In 2021 Based On Crunchbase
    Top 10 Blockchain Security and Smart Contract Audit Companies
    The 20 Best Cybersecurity Startups To Watch In 2020
    Blockchain In Cybersecurity: 11 Startups To Watch In 2019
    004-STM32+BC26丨260Y基本控制篇(阿里云物联网平台)-在阿里云物联网平台上一型一密动态注册设备(Android)
    涂鸦开发-单片机+涂鸦模组开发+OTA
    000-ESP32学习开发-ESP32烧录板使用说明
    03-STM32+Air724UG远程升级篇OTA(阿里云物联网平台)-STM32+Air724UG使用阿里云物联网平台OTA远程更新STM32程序
    03-STM32+Air724UG远程升级篇OTA(自建物联网平台)-STM32+Air724UG实现利用http/https远程更新STM32程序(TCP指令,单片机程序检查更新)
  • 原文地址:https://www.cnblogs.com/BestMePeng/p/AngularJS_Event.html
Copyright © 2011-2022 走看看