2015-11-28 10 views
8

私はAngularJSとui-routerの新しいユーザーです。スコープの管理方法について頭を下げようとしています。私はアクティブコントローラのスコープが状態変化時に無効になったときに破壊されると予想していましたが、そうではありません。UI-Router - スコープが状態変化で破棄されませんか?

私は状況を説明するためにUI-Routerのウェブサイトからこの例を変更しました(下記の参照)。状態route1.list/route2.listがトリガされるたびに、$ rootScopeでイベントを送出します。イベントを受け取ると、debugステートメントがコンソールに出力されます。

2つの状態を数回切り替えると、以前に初期化されたすべてのコントローラがイベントに応答したことがわかります。だから彼らによって作られたスコープは決して破壊されていないようです。この動作は期待されていますか?もしそうなら、アクティブなコントローラーだけがイベントに応答するように私は何をすべきですか?コンソール上に印刷

Plunker

デバッグメッセージ: enter image description here

コード:ここで

var myapp = angular.module('myapp', ["ui.router"]) 
myapp.config(function($stateProvider, $urlRouterProvider){ 

// For any unmatched url, send to /route1 
$urlRouterProvider.otherwise("/route1") 

がroute1の

$stateProvider 
    .state('route1', { 
     url: "/route1", 
     templateUrl: "route1.html" 
    }) 
    .state('route1.list', { 
     url: "/list", 
     templateUrl: "route1.list.html", 
     controller: function($rootScope, $scope){ 
      $rootScope.$emit("eventCT1"); 
      $rootScope.$on("eventCT2", fn); 
      function fn() { 
      console.log("Controller 1 receives an event emitted by Controller 2"); 
      } 
      $scope.items = ["A", "List", "Of", "Items"]; 
     } 
    }) 

であり、ここで、経路2

あります
.state('route2', { 
     url: "/route2", 
     templateUrl: "route2.html" 
    }) 
    .state('route2.list', { 
     url: "/list", 
     templateUrl: "route2.list.html", 
     controller: function($rootScope, $scope){ 
      $rootScope.$emit("eventCT2"); 
      $rootScope.$on("eventCT1", fn); 
      function fn() { 
      console.log("Controller 2 receives an event emitted by Controller 1"); 
      } 
      $scope.things = ["A", "Set", "Of", "Things"]; 
     } 
    }) 
... 

答えて

4

我々は、)を非常に限られた寿命を持つコントローラ(の内部

1)$rootScopeで何かをしたい場合は、我々はそれを破壊しなければならない

2)、コントローラ(実際にはその$scopeが破壊されています

これは、フックとアンフックの方法です。

// get remove function 
var removeMe = $rootScope.$on("eventCT2", ...); 

// call that function 
$scope.$on("$destroy", removeMe) 
しかし、上記の場合には、私たちも...

1)一つの状態のためのいくつかのコントローラのアクションを作成する

2を試してみてください)、それは他に呼び出されます期待すべきではありません別の状態からコントローラ

あなたは角度でイオンを使用している場合、これらは一緒に

+0

ご協力ありがとうございます。以前のコントローラが状態の変化で破壊された場合、$ rootScope。$ on(name、listener)で登録されたリスナーは定義されないはずですか?なぜそれが引き金になって、エラーが投げられないのですか? – CLDev

+0

これは「閉鎖」です。コントローラーを表すオブジェクト全体(および参照するすべてのオブジェクト)は、リスナーとして機能するためにメモリに保持されます。それがメモリリークを生み出す最良の方法です。私は、クロージャについて読むことをお勧めします。ほとんどの場合、 '$ rootScope'を使用しないでください。コントローラレベルで登録を解除しないでください。少し助けてくれることを願っています。 UIルーターと角をお楽しみください。それがあなたを助けたら、あなたは答えを受け入れることができます... –

+1

ああ..理解!ありがとうございました。 – CLDev

-1

を生きることはありません、あなたはそうのようなlife cycle eventsを使用することができます:

$scope.$on("$ionicView.beforeEnter", function(){ 
    //Do something every time this controller is the active scope. 
}) 

上記のリンクで提供されている他のイベントでも遊ぶことができます。 $emitの使用を最小限に抑えることがベストプラクティスであり、より予測可能なコードとより少ない状態の変異につながります。

+0

あなたの助けに。残念ながら、私のプロジェクトはIonicフレームワークを使用していないので、私はそれがあると予期していません。だから私はおそらく他のオプションを探さなければならないだろう。 – CLDev

関連する問題