2016-07-03 9 views
0

角度コントローラのイベント($rootScopeやソケットイベントなど)を正しく処理するにはどうすればよいですか?コントローラーが破壊されていないという問題に直面しています。これは、特定のイベントを聴いているときにいくつかの問題を引き起こします。私がここで言いたいことを明確にする角度コントローラの寿命とイベント処理

はplunkerです:http://plnkr.co/edit/CkXKUnpUdsbnZEjq8zLy?p=preview

は、最初の場所で(ボタンをクリックして)rootscopeイベントをトリガ意図したとおりに動作します:ただ一つのイベントを取り込みます。しかし、Route 2にナビゲートし、再度rootscopeイベントをトリガーすると私の問題が示されます。両方のコントローラがアクティブになっているので(少なくとも私の推測であるので)、イベントは2回フェッチされます。すべてのルートスイッチにより、追加のイベントリスナが発生します。

これを処理する方法は?

答えて

1

$rootScope.$onの代わりに$scope.$onを使用すると、リスナーは自動的に有効範囲破壊時に破棄されます。

+0

よろしくお願いいたします。ちょうど1つの問題が残っています:ソケットイベント( 'socket.on( 'event'、...)')がサービス内に配置され、コントローラ内に配置される必要がないということでしょうか?ソケットイベントのリッスンは '$ rootScope'イベントのリッスンと同じように動作し、複数回トリガすることができます。 – nehalist

1

JosselinTDによって与えられた答えは正しいです。イベントが$ rootScopeでブロードキャストされている場合は、イベントがトリガされたスコープの下に階層的に存在し、他のすべてのスコープが$ rootScopeの下にあるすべてのスコープでブロードキャストがトリガされるので、それぞれのコントローラの$スコープでリッスンすれば十分です。

これはオプションではない場合、たとえば($ broadcastの代わりに$ emitメソッドを使用して)放出されたイベントを捕まえたいので、あなたの$ scopeを渡さないので、実際には$ rootScopeでも聞くことができます。その場合、あなたは、コントローラのスコープが破棄されたときに、リスナーをクリーンアップすることを、しかし、確認する必要があります:

var removeListener = $rootScope.$on('yourEvent', function(event) { 
    // do what you want here.. 
}); 
// remove the listener on $rootScope when $scope is cleaned up 
// this makes sure we have no unwanted references.. 
$scope.$on('$destroy', removeListener); 

法上の$は、それによって作成されたリスナーを削除することを可能にする機能を返します。 AngularJSは、コントローラが破棄されたとき(例えば、そのビューが別のものに置き換えられたなど)、$ scopeの$ destroyイベントを呼び出します。

あなたはまた、socket io listener removal (stackoverflow)

有用であるかもしれないもう一つのヒントで説明したようにそれがリスナーの除去であるかもしれない

$scope.$on('$destroy', function() { 
    //TODO: call some clean-up function to remove your event listener 
}); 

を使用する必要があり、コントローラ内の非アンギュライベントを聴いている場合: AngularJSのコンテキスト外(例えばDOMイベントにも適用されますが、確かにsocket.ioイベントにも適用されます)から来るイベントを聴いている場合は、$ scopeでそれらをラップする必要があります。イベントリスナーによってもたらされた変更の

socket.on('someSocketEvent', function(data) { 
    $scope.$apply(function() { 
    $scope.dataFromSocket = data; 
    }); 
});