[英]AngularJS: Listen to events, one after the other
是否有一种角度方式来监听一个接一个发生的事件? 例如,我想在$rootScope
上监听$routeChangeSuccess
和$viewContentLoaded
事件。 当第一个事件发生时,之后发生第二个事件,我想调用一个回调函数。
这可能吗? 或者我必须自己写吗? 配置事件的顺序是否重要也是很好的。 或者任何想法,如何实现这样的行为?
更新
因为我没有在网上找到任何东西,所以我提出了自己的解决方案。 我认为它有效,但我不知道这种方法是否有任何缺点。
以及如何将此全局集成到AngularJS项目中的任何建议? 或者甚至作为凉亭组件? 我应该将函数附加到作用域还是rootScope? 任何帮助表示赞赏!
这是Plunker链接和代码: http ://plnkr.co/edit/slfvUlFCh7fAlE4IPt8o?p = preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.events = [];
var successiveOn = function(events, eventScope, callback, orderImportant) {
// array for the remove listener callback
var removeListenerMethods = [];
// events array that is passed to the callback method
var eventsArr = [];
// how many events are fired
var eventCount = 0;
// how many events should be fired
var targetEventCount = events.length;
// track the next event, only for orderImportant==true
var nextEvent = events[0];
// iterate over all event strings
for (var i = 0; i < events.length; i++) {
var event = events[i];
// attach an $on listener, and store the remove listener function
var removeListener = eventScope.$on(event, function(evt) {
if (evt.name == nextEvent || !orderImportant) {
++eventCount;
nextEvent = events[eventCount];
eventsArr.push(evt);
// if all events has fired, call the callback method and reset
if (eventCount >= targetEventCount) {
callback(eventsArr);
nextEvent = events[0];
eventCount = 0;
eventsArr = [];
}
}
});
removeListenerMethods.push(removeListener);
}
// the return function is a anonymous function which calls all the removeListener methods
return function() {
for (var i = 0; i < removeListenerMethods.length; i++) {
removeListenerMethods[i]();
}
}
}
// order is unimportant
var removeListeners = successiveOn(["orderUnimportant1", "orderUnimportant2", "orderUnimportant3"], $scope, function(events) {
var str = "Events in order of trigger: ";
for (var i = 0; i < events.length; i++) {
str += events[i].name + ", ";
}
$scope.events.push(str);
}, false);
$scope.$broadcast("orderUnimportant1");
$scope.$broadcast("orderUnimportant2");
$scope.$broadcast("orderUnimportant3"); // Events were triggered 1st time
$scope.$broadcast("orderUnimportant3");
$scope.$broadcast("orderUnimportant2");
$scope.$broadcast("orderUnimportant1"); // Events were triggered 2nd time, order doesn't matter
removeListeners();
// order is important!
var removeListeners = successiveOn(["OrderImportant1", "OrderImportant2", "OrderImportant3"], $scope, function(events) {
var str = "Events in order of trigger: ";
for (var i = 0; i < events.length; i++) {
str += events[i].name + ", ";
}
$scope.events.push(str);
}, true);
$scope.$broadcast("OrderImportant1");
$scope.$broadcast("OrderImportant2");
$scope.$broadcast("OrderImportant3"); // Events were triggered
$scope.$broadcast("OrderImportant1");
$scope.$broadcast("OrderImportant3");
$scope.$broadcast("OrderImportant2"); // Events were NOT triggered
removeListeners();
});
使用$q
服务即承诺。
var routeChange = $q.defer();
var contentLoaded = $q.defer();
$rootScope.$on("$routeChangeSuccess", function() {
routeChange.resolve();
});
$rootScope.$on("$viewContentLoaded", function() {
contentLoaded.resolve();
});
$q.all([contentLoaded.promise, routeChange.promise]).then(function() {
//Fire your callback here
});
具体订单:
routeChange.then(function() {
contentLoaded.then(function () {
//Fire callback
});
});
没有令人讨厌的回调汤:
var routeChangeHandler = function() {
return routeChange.promise;
}
var contentLoadedHandler = function() {
return contentLoaded.promise
}
var callback = function() {
//Do cool stuff here
}
routeChangeHandler
.then(contentLoadedHandler)
.then(callback);
那该死的性感......
我认为如果你想用纯粹的AngularJS设施来解决这个问题,Stens的答案就是解决这个问题的最佳方法。 但是,这种情况经常表明你必须定期处理更复杂的事件。 如果是这种情况,我建议你看一下Reactive Extensions和rx.angular.js桥接库。
使用Reactive Extensions for JavaScript(RxJS),您可以将代码简化为:
Rx.Observable.combineLatest(
$rootScope.$eventToObservable('$routeChangeSuccess'),
$rootScope.$eventToObservable('$viewContentLoaded'),
Rx.helpers.noop
)
.subscribe(function(){
//do your stuff here
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.