Подтвердить что ты не робот

Прослушать несколько событий в $scope

У меня есть директива, которая связывает некоторые функции с локальной областью с $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');
            });
        }
    };
});

Но это не идеально.

Возможно ли связать несколько событий с одной и той же функцией за один раз?

4b9b3361

Ответ 1

Да. Вот так:

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');});
        }
    };
});

Но только потому, что вы можете, это не значит, что вы должны:). Если события продолжают распространяться до другого слушателя, и они обрабатываются по-другому, возможно, есть случай сделать это. Если это будет единственный слушатель, вы должны просто выпустить (или передать) одно и то же событие.

Ответ 2

Другие ответы (Anders 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(','), вы могли бы, но это была деталь реализации.

Ответ 3

AngularJS не поддерживает множественную привязку событий, но вы можете сделать что-то вроде этого:

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

Ответ 4

Я не думаю, что это возможно, поскольку событие может отправлять данные в обратный вызов, и если вы слушаете несколько событий, вы не знаете, какие данные пришли из какого-либо события.

Я бы сделал что-то вроде этого:

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

Ответ 5

Также как с $rootScope. $onMany (решение от @ben-lesh) можно расширить метод $on:

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);
  });

};

взял здесь.