zoukankan      html  css  js  c++  java
  • AngularJS 事件广播与接收 $broadcast,$emit,$on 作用域间通信 封装factory服务 发布订阅

      不同作用域之间通过组合使用$broadcast,$emit,$on的事件广播机制来进行通信。

    一、说明

    1、广播

      $broadcast

        说明:将事件从父级作用域传播至本作用域及子级作用域。

        格式:$broadcast(eventName,args)

      $emit

        说明:将事件从子级作用域传播至本作用域及父级作用域,直至根作用域。

        格式:$emit(eventName,args)

    2、接收

      $on

        说明:在作用域中监控从子级或父级作用域中传播过来的事件及相应的数据。

        格式:$on(eventName,function(event,data){ })

        event说明:   

          event.targetScope //获取传播事件的作用域
          event.currentScope //获取接收事件的作用域
          event.name //传播的事件的名称
          event.stopPropagation() //阻止事件进行冒泡传播,仅在$emit事件中有效 ,当前作用域的上层作用域就不能再接收到消息事件
          event.preventDefault() //阻止传播事件的发生
          event.defaultPrevented //如果调用了preventDefault事件则返回true

    二、例子

    1、$scope.$emit

      由子作用域向上级作用域传播数据。

    <!DOCTYPE html>
    <html ng-app="myApp">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
        <meta charset="utf-8" />
        <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
    </head>
    <script>
        var myApp = angular.module("myApp", []);
    
        //控制器Parent
        myApp.controller("Parent", function ($scope, $window) {
          $scope.name = "Parent";
          $scope.$on("fromChild", function (event, data) {
            $window.alert("当前节点" + event.currentScope.name + ",截获到了来自" + data.divName + "的事件:" + event.name + ",它的作用是" + data.description);
          });
     
        });
        //控制器Child
        myApp.controller("Child", function ($scope, $window) {
          $scope.toTop = function () {
            //向上传播的事件,eventName:'fromChild', data:oneObject
            $scope.$emit("fromChild", { divName: "child", description: "向上播数据" });
          };
     
        });
      </script>
     
    </head>
    <body>
      <form> 
      <div ng-controller="Parent">
          <div ng-controller="Child">
            <input type="button" ng-click="toTop()" value="向上传播事件" />
          </div>
        </div> 
      </div>
      </form>
    </body> 
    </html>

      运行结果

      

    2、event.stopPropagation()

      阻止事件进行冒泡传播,仅在$emit事件中有效 ,当前作用域的上层作用域就不能再接收到消息事件。

      上个例子原来应该rootScope也能收到事件消息,如果加一句event.stopPropagation(),rootScope就不能收到事件数据。

      代码修改如下:

    //控制器Parent
        myApp.controller("Parent", function ($scope, $window) {
          $scope.name = "Parent";
          $scope.$on("fromChild", function (event, data) {
            $window.alert("当前节点" + event.currentScope.name + ",截获到了来自" + data.divName + "的事件:" + event.name + ",它的作用是" + data.description);
            event.stopPropagation();
          });
     
        });

    三、项目实例

      子作用域 childScope

     <div class="panel-heading" style="border-radius: 5px 5px 0 0; background-color: #608FB7;padding:10px;">
            <strong>
                {{focusedInput.inputType}}: #{{focusedInput.tooth.code2}}
                {{focusedInput.toothSurface|toToothSurfaceString}}
                &nbsp;{{focusedInput|toPerioInputPositionName}}
            </strong>
        </div>
    <div class="panel-body perio-input-board" style="padding:5px;margin-left:8px;">
            <div style=" 180px;float:left" class="perio-input-number-board">
                <button type="button" class="btn btn-lg btn-default" ng-click="setValue(1)">1</button>
            </div>
           
        </div>

      $emit向上层作用域发送消息广播,消息名称“perioInputFinished”,消息数据对象$scope.focusedInput

    var setValue = function (value) {
      if ($scope.focusedInput) {
         $scope.$emit('perioInputFinished', $scope.focusedInput);
       }
    };

      

     上级作用域parentScope

      注册和接收,消息事件“perioInputFinished”,后又向子作用域广播,消息“perioValueChanged”,这样发送消息源作用域的兄弟作用域也可以收到消息事件

     var init = function () {
       //监控消息广播 $scope.$on(
    'perioInputFinished', onPerioInputFinished); };

     //监控到后,接收又广播
     var onPerioInputFinished = function (event, perioInput) {
           $scope.$broadcast('perioValueChanged', perioInput);
     };

      下级作用域childScope1

      接收到“perioValueChanged”消息后,通过名称联系,进行最终处理,onPerioValueChanged 

    var onPerioValueChanged = function (event, perioInput) {
      if (perioInput.arch == $scope.arch && perioInput.toothSurface == $scope.toothSurface
         && (perioInput.inputType == 'PD' || perioInput.inputType == 'GM')) {
                        refreshLine();
        }
    };
    
    var init = function () {          
       $scope.$on('perioValueChanged', onPerioValueChanged);
    };

    四、封装成服务factory方式

      发布订阅模式

    app.factory('eventAggregator', ['$log', '$rootScope', function ($log, $rootScope) {
        'use strict';
    
        var events = {
            ChargeOrderCreated: 'ChargeOrderCreated',
            SelectedEmployee: 'SelectedEmployee'
        };
    
        var publish = function (event, eventData, sender) {
            $log.debug('[eventAggregator] publish(): ' + event);
            $rootScope.$broadcast(event, eventData, sender);
        };
    
        $('body').on('sidebar-toggled', function (event, isCollapsed) {
            $rootScope.isSideBarCollapsed = isCollapsed;
            publish(events.AppSideBarToggled, null);
        });
    
        return {
            events: events,
            publish: publish,
            subscribe: function (scope, event, callback) {
                return scope.$on(event, callback);
            }
        };
    }
    ]);

       使用方式:

      订阅:$scope.$on

      var subscribeEvent = function () {
        eventAggregator.subscribe($scope, eventAggregator.events.ChargeOrderCreated, refresh);
      };

      发布:$rootScope.$broadcast

        eventAggregator.publish(eventAggregator.events.ChargeOrderCreated, chargeData, eventSender);

      

  • 相关阅读:
    [stm32] Systick
    [stm32] GPIO及最小框架
    51单片机-PC数据传输 温度 距离 监控系统设计
    [游戏学习29] Win32 图像处理1
    [51单片机] 串口通讯 简单通信
    [汇编] 闰年计算
    Java常用工具类之ArrayUtil
    常用工具类系列之DateUtil
    SpringBoot 获取当前登录用户IP
    Spring data jpa Specification查询关于日期的范围搜索
  • 原文地址:https://www.cnblogs.com/shawnhu/p/8468835.html
Copyright © 2011-2022 走看看