簡體   English   中英

AngularJS:一個接一個地聽取事件

[英]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 Extensionsrx.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM