欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

AngularJS 事件发布机制

程序员文章站 2023-02-22 11:18:56
问题描述 未读消息提醒 当器具用户或技术机构对非强检器具检校申请发布新的意见时,需要对对方进行消息通知。 后台很简单,本文主要解决前台遇到的问题。 历史遗留...

问题描述

未读消息提醒

当器具用户或技术机构对非强检器具检校申请发布新的意见时,需要对对方进行消息通知。

后台很简单,本文主要解决前台遇到的问题。

AngularJS 事件发布机制

历史遗留

这是我的消息遗留下来的统计未读消息的指令,用到了缓存supercache

一眼看去应该能发现这个if...else的问题,第一次请求,将数据放到缓存里,之后就一直从缓存中取了,这肯定有问题啊!原来有1条消息,然后点击查看,然后这个指令仍然是从缓存中取的数据,还显示一条。

angular.module('webappapp')
  .directive('yunzhiunreadmessagecount', function(tomessageservice, supercache) {
    return {
      template: '',
      restrict: 'e', // 元素
      link: function postlink(scope, element) {
        // 判断缓存中是否存在未读消息数量
        if (typeof supercache.get('unreadmessagecount') === 'undefined') {
          // 获取当前用户的所有未读收件消息
          tomessageservice.pagereceiveunreadmessageofcurrentuser(undefined, function(data) {
            // 存入缓存
            supercache.put('unreadmessagecount', data.totalelements);
            // 显示文本信息
            element.text(supercache.get('unreadmessagecount'));
          });
        } else {
          // 显示文本信息
          element.text(supercache.get('unreadmessagecount'));
        }
      }
    };
  });

功能实现

注销时清除缓存

注销时如果不清除缓存,下一个用户登录时用的就是上一用户留下来的缓存,造成信息提示错误。

AngularJS 事件发布机制

阅读时重新执行指令

下图就是该实现的难点。

该用户有一条未读消息,当用户点击阅读这条消息时,将该消息的状态设置为已读,然后右上角的未读条数同时修改。但是点击这个事件是发生在控制器中,而消息又是一个额外的指令,两者毫无联系。

AngularJS 事件发布机制

angularjs的精髓就是scope,这是两个scope,页面内容是我们的控制器scope,右上角的消息处是我们的未读消息指令scope

如若是简单的父子scope关系,我们可以从控制器传参数到指令,指令watch这个参数,根据控制器对参数的变动让指令做出响应。但是这两个scope毫无关系,我们怎么办呢?

AngularJS 事件发布机制

事件发布

查阅了相关资料,angularjsscope可以发布事件。

$broadcast(name, args);

dispatches an event name downwards to all child scopes (and their children) notifying the registered $rootscope.scope listeners.

向下分发一个事件给他的所有子scope,通知已注册的scope

$emit(name, args);

dispatches an event name upwards through the scope hierarchy notifying the registered $rootscope.scope listeners.

$broadcast类似,只不过这个是用来向上发布事件的。

$on(name, listener);

listens on events of a given type.

监听一个给定类型的事件。

实例说明angularjs $broadcast $emit $on的用法

<div ng-controller="parentctrl">         //父级 
  <div ng-controller="selfctrl">        //自己 
    <a ng-click="click()">click me</a> 
    <div ng-controller="childctrl"></div>   //子级 
  </div> 
  <div ng-controller="broctrl"></div>      //平级 
</div> 

js代码

appcontrollers.controller('selfctrl', function($scope) { 
  $scope.click = function () { 
    $scope.$broadcast('to-child', 'child'); 
    $scope.$emit('to-parent', 'parent'); 
  } 
}); 

appcontrollers.controller('parentctrl', function($scope) { 
  $scope.$on('to-parent', function(d,data) { 
    console.log(data);     //父级能得到值 
  }); 
  $scope.$on('to-child', function(d,data) { 
    console.log(data);     //子级得不到值 
  }); 
}); 

appcontrollers.controller('childctrl', function($scope){ 
  $scope.$on('to-child', function(d,data) { 
    console.log(data);     //子级能得到值 
  }); 
  $scope.$on('to-parent', function(d,data) { 
    console.log(data);     //父级得不到值 
  }); 
}); 

appcontrollers.controller('broctrl', function($scope){ 
  $scope.$on('to-parent', function(d,data) { 
    console.log(data);    //平级得不到值 
  }); 
  $scope.$on('to-child', function(d,data) { 
    console.log(data);    //平级得不到值 
  }); 
}); 

点击click me的输出结果

child 
parent 

代码实现

$rootscope

考虑到这两个控制器与指令之间scope的关系,无论是向上还是向下可能都接收不到。

这里直接用$rootscope向下发布事件,保证所有scope都能获取到该事件。免得去考虑当前scope与目的scope之间的关系。

// 广播发布reloadmessagecount事件,重新计算未读消息数量
$rootscope.$broadcast('reloadmessagecount');

因为考虑到各个层之间的职责关系,我认为:事件发布应该方法控制器中,而不应该放在service中,service就等着被别人调用,不应该与其他文件有耦合关系,否则改起来很难改。

$on

重构指令,使用$on监听事件发布,执行相应的逻辑重新显示右上角的未读消息数。

angular.module('webappapp')
  .directive('yunzhiunreadmessagecount', function(tomessageservice, supercache) {
    return {
      template: '<b ng-if="count">{{ count }}</b>',
      restrict: 'e', // 元素
      link: function postlink(scope) {
        var self = this;

        self.init = function() {
          self.computemessagecount();
        };

        // 计算未读消息数量
        self.computemessagecount = function() {
          // 判断缓存中是否存在未读消息数量
          if (angular.isundefined(supercache.get('unreadmessagecount'))) {
            // 获取当前用户的所有未读收件消息
            tomessageservice.pagereceiveunreadmessageofcurrentuser(undefined, function(data) {
              // 存入缓存
              supercache.put('unreadmessagecount', data.totalelements);
              // 显示
              scope.count = supercache.get('unreadmessagecount');
            });
          } else {
            scope.count = supercache.get('unreadmessagecount');
          }
        };

        // 处理reloadmessagecount事件的处理逻辑
        scope.$on('reloadmessagecount', function() {
          // 清除缓存
          supercache.remove('unreadmessagecount');
          // 计算未读消息数量
          self.computemessagecount();
        });

        // 初始化
        self.init();
      }
    };
  });

AngularJS 事件发布机制

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。