web-dev-qa-db-ja.com

AngularJsサービスでカスタムイベントを作成する方法

私はAngularJsプロジェクトに取り組んでいます。一部のボタンのイベントを設定および削除するサービスがあります。このサービスは、ボタンと直接やり取りしたくない別のサービスによって利用されます。ただし、ボタンクリックイベントを最初のサービスでフィルター処理し、2番目のサービスで処理したいと思います。 2番目のサービスにボタンを認識させたくないので、最初のサービスでカスタムイベントを作成する必要があると考えています。ボタンがクリックされたときにカスタムイベントを作成して起動するにはどうすればよいですか?

前もって感謝します。

35
rmg.n3t

サービス/ディレクティブ間でイベントを送信する場合は、broadcastを使用します。

$rootScope.$broadcast('buttonPressedEvent');

そして、このように受け取ります:

$rootScope.$on('buttonPressedEvent', function () {
             //do stuff
        })
82
Chancho

グローバルなスコープベースの統合はネームスペースを傷つけ、中規模および大規模のアプリケーションでひどい副作用を引き起こす可能性があります。プロキシサービスを使用して、もう少し複雑ですが、間違いなくクリーンなソリューションをお勧めします。

1。プロキシサービスの作成

angular.module('app').service('userClickingHelper', [
  function() {
    var listeners = [];
    return {
      click: function(args) {
        listeners.forEach(function(cb) {
          cb(args);
        });
      },
      register: function(callback) {
        listeners.Push(callback);
      }
    };
  }
]);

2。依存関係としてuserClickingHelperを使用しているボタンディレクティブを作成します。

angular.module('app').directive('onDistributedClick', ['userClickingHelper', function (userClickingHelper) {
    return {
        restrict: 'A',
        link: function (scope, element) {
            element.on('click', userClickingHelper.click);
        }
    };
}]);

。プロキシを使用して無関係なサービスを登録します。

angular.module('app').service('myUnrelatedService', [function (userClickingHelper) {
    userClickingHelper.register(function(){
        console.log("The button is clicked somewhere");
    });
}]);

その結果、イベント配信の孤立したスコープが得られますが、ディレクティブもサービスも互いを認識しません。ユニットテストも簡単です。

グローバルにアクセス可能な「読み込み」モーダルにも同様のソリューションを使用しているため、コントローラー/サービスが「ユーザーは今すぐクリックしないでください」と言っている方法を抽象化できます。

34
Mano Kovacs

要素で次のものを使用してイベントを作成および発行できます

ng-click="$emit('customEvent')"

次に、あなたのコントローラで使用することができます

$rootScope.$on('customEvent', function(){
    // do something
})

デモ

8
Jonathan de M.