AngularJS$范围$关于多个事件

AngularJS $scope.$on multiple events

本文关键字:事件 于多个 范围 AngularJS      更新时间:2023-09-26

我有一个场景,需要监听通过$scope.$emit传输的两个不同事件,并且只有当这两个事件都发生时,我才想执行

例如,如果触发的事件如下:

$scope.$emit('first');
// do nothing
$scope.$emit('second');
// execute something
$scope.$emit('first');
// Do nothing
$scope.$emit('first');
// Do nothing
$scope.$emit('second');
// execute something

有什么东西可以开箱即用吗?理想情况下类似

$scope.$on('first', 'second', function() {});

我考虑过做以下事情:

var triggeredEvents = [];
$scope.$on('first', function() {
    notifyEventTriggered('first');
});
$scope.$on('second', function() {
    notifyEventTriggered('second');
});
function notifyEventTriggered(event) {
    if (triggeredEvents.indexOf(event) == -1) {
         triggeredEvents.push(event);
    }
    if (triggeredEvents.length > 1) {
        execute();
        triggeredEvents.length = 0;
    }
}

那么,有什么能让它更简单吗?或者对如何改进它提出一些建议?除了为此创建服务之外。

感谢

没有内置的方法。我个人会在$rootScope中附加一个新方法,如下所示:

https://jsfiddle.net/qv6m2drz/5/

var app = angular.module('jsbin', []);
app.run(['$rootScope', function($rootScope) {
  $rootScope.onAllEvents = (function() {
    var watchedEvents = {};    
    return onAllEvents;
    /*
     * Attach listeners to all events
     */
    function onAllEvents(events, fn){
        if(!events || !events.length) return ;
      events.forEach(function(evt){
        watchedEvents[evt] = false;
        this.$on(evt, function(){
            watchedEvents[evt] = true;
          tryExecute(fn);
        });
      }.bind(this));
    }
    /* 
     * Check if all `watchedEvents` have fired. If yes, run fn() and reset the events
     */
    function tryExecute(fn){
        var shouldExecute = true;
        for(evt in watchedEvents){
        if(watchedEvents.hasOwnProperty(evt) && !watchedEvents[evt]){
            shouldExecute = false;
        }
      }
      if(shouldExecute){        
        fn();
        for(evt in watchedEvents){
          if(watchedEvents.hasOwnProperty(evt)){
            watchedEvents[evt] = false;
          }
        }
      }
    }
  })();
}]);