2013-02-12 92 views
19

我有一個指令將一些函數綁定到本地範圍$scope.$on

是否可以將同一個函數綁定到一個調用中的多個事件?

理想我可以做這樣的事情:

app.directive('multipleSadness', function() { 
    return { 
     restrict: 'C', 
     link: function(scope, elem, attrs) { 
      scope.$on('event:auth-loginRequired event:auth-loginSuccessful', function() { 
       console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks'); 
      }); 
     } 
    }; 
}); 

但是,這是行不通的。以逗號分隔的事件名稱字符串替換爲['event:auth-loginRequired', 'event:auth-loginConfirmed']的示例也不例外。

什麼工作是這樣的:

app.directive('multipleSadness', function() { 
    return { 
     restrict: 'C', 
     link: function(scope, elem, attrs) { 

      scope.$on('event:auth-loginRequired', function() { 
       console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks'); 
      }); 
      scope.$on('event:auth-loginConfirmed', function() { 
       console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks'); 
      }); 
     } 
    }; 
}); 

但這並不理想。

是否可以將多個事件綁定到同一個函數中?

回答

11

是。像這樣:

app.directive('multipleSadness', function() { 
    return { 
     restrict: 'C', 
     link: function(scope, elem, attrs) { 

      function sameFunction(eventId) { 
       console.log('Event: ' + eventId + '. The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks.'); 
      } 

      scope.$on('event:auth-loginRequired', function() {sameFunction('auth-loginRequired');}); 
      scope.$on('event:auth-loginConfirmed', function() {sameFunction('auth-loginConfirmed');}); 
     } 
    }; 
}); 

但只是因爲你可以,並不意味着你應該:)。如果事件繼續傳播到另一個偵聽器,並且它們在那裏處理方式不同,那麼可能有這種情況。如果這將是唯一的監聽者,那麼你應該發出(或廣播)同一個事件。

+0

感謝有關事件傳播和事件ID的額外信息,瞭解這一點,我明白爲什麼我所要求的不是本地可能的。事件確實有不同的監聽器,但是這個監聽器需要對多個事件執行相同的操作。 – 2013-02-12 20:02:00

+0

經過考慮,我將我的代碼重構爲更多* Angular *。還有兩個事件,但由於它們表示不同的事物(在重構中),所以沒有理由將它們綁定到相同的函數。感謝指針。 – 2013-02-13 08:35:40

+0

完全沒問題。很高興我能幫上忙。 – testing123 2013-02-13 16:29:21

7

我不認爲這是可能的,因爲事件可能會將數據發送到回調函數,並且如果您聆聽多個事件,則不知道哪個數據來自哪個事件。

我會做這樣的事情:

function listener() { 
    console.log('event fired'); 
} 
scope.$on('event:auth-loginRequired', listener); 
scope.$on('event:auth-loginConfirmed', listener); 
13

AngularJS不支持多個事件綁定,但你可以做這樣的事情:

var handler = function() { ... } 
angular.forEach("event:auth-loginRequired event:auth-loginConfirmed".split(" "), function (event) { 
    scope.$on(event, handler); 
}); 
+1

是否有一個原因,你會使用「事件:auth-loginRequired事件:auth-loginConfirmed」.split(「」)而不是隻是['event:auth-loginRequired','event:auth-loginConfirmed']? – 2013-02-12 14:34:53

+0

@ RyanO'Neill沒有什麼特別的理由=)它似乎比擁有['','','',...]的單個字符串更整齊。另外OP的例子是用逗號分隔的單個字符串。 – bmleite 2013-02-12 14:55:28

+2

謝謝。 JavaScript就是這樣,只是想確保我沒有錯過我應該知道的Wat時刻。 – 2013-02-12 14:58:57

27

其他的答案(安德斯Ekdahl)是100%正確的......挑其中的一個...但是...

除非,你總是可以滾你自己:

// a hack to extend the $rootScope 
app.run(function($rootScope) { 
    $rootScope.$onMany = function(events, fn) { 
     for(var i = 0; i < events.length; i++) { 
     this.$on(events[i], fn); 
     } 
    } 
}); 

app.directive('multipleSadness', function() { 
    return { 
     restrict: 'C', 
     link: function(scope, elem, attrs) { 
      scope.$onMany(['event:auth-loginRequired', 'event:auth-loginSuccessful'], function() { 
       console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks'); 
      }); 
     } 
    }; 
}); 

我想如果你真的想做.split(',')你可以,但這是一個實現細節。 。

+1

您應該將此作爲PR提交,我可以使用它。也許我會拿你的信用。 – 2013-10-19 03:40:11

+1

檢查每次迭代的長度是非常昂貴的;最好將長度分配給變量 – 2014-07-05 06:45:18

+7

@VerdiErelErgün「非常昂貴」?每毫秒你有多少次解釋這個問題?這是一次性調用來設置一些綁定。微優化在這裏不是真正的重點......但是,是的,我們可以爲(var i = 0,len = events.length; i 2014-07-07 07:10:06

1

還與$ rootScope $ onMany(來自@奔故障溶液)喜歡它可能在方法擴展$:

var $onOrigin = $rootScope.$on; 

$rootScope.$on = function(names, listener) { 
    var self = this; 

    if (!angular.isArray(names)) { 
    names = [names]; 
    } 

    names.forEach(function(name) { 
    $onOrigin.call(self, name, listener); 
    }); 

}; 

here了。

+1

如果您希望子範圍也繼承修改的函數,則應修改'$ rootScope .__ proto __。$ on'(或'$ rootScope.constructor.prototype。$ on')。 – cipak 2017-01-20 09:44:19