21

いくつかの関数をローカルスコープにバインドするディレクティブがあり$scope.$onます。

1回の呼び出しで同じ関数を複数のイベントにバインドすることは可能ですか?

理想的には、次のようなことができるでしょう。

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

しかし、これは理想的ではありません。

複数のイベントを一度に同じ関数にバインドすることは可能ですか?

4

5 に答える 5

29

他の答え(アンダースエクダール)は100%正しいです...それらの1つを選んでください...しかし...

それを除けば、あなたはいつでもあなた自身を転がすことができます:

// 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(',')できると思いますが、それは実装の詳細です。

于 2013-02-12T16:15:15.173 に答える
14

AngularJSは複数のイベントバインディングをサポートしていませんが、次のようなことができます。

var handler = function () { ... }
angular.forEach("event:auth-loginRequired event:auth-loginConfirmed".split(" "), function (event) {
    scope.$on(event, handler);
});
于 2013-02-12T14:16:13.550 に答える
13

はい。このような:

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

しかし、できるからといって、そうすべきだという意味ではありません:)。イベントが別のリスナーに伝播し続け、そこで異なる方法で処理される場合は、これを行う場合があります。これが唯一のリスナーになる場合は、同じイベントを発行(またはブロードキャスト)する必要があります。

于 2013-02-12T14:17:14.193 に答える
8

イベントがコールバックにデータを送信する可能性があり、複数のイベントをリッスンすると、どのデータがどのイベントからのものかわからないため、それは不可能だと思います。

私はこのようなことをしたでしょう:

function listener() {
    console.log('event fired');
}
scope.$on('event:auth-loginRequired', listener);
scope.$on('event:auth-loginConfirmed', listener);
于 2013-02-12T13:47:01.580 に答える
1

また、$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);
  });

};

ここから取った。

于 2015-06-07T19:51:46.123 に答える