AngularJSコントローラーのライフサイクルは何ですか?


199

誰かがAngularJSコントローラーのライフサイクルを明確にできますか?

  • コントローラはシングルトンですか、それともオンデマンドで作成/破棄されますか?
  • 後者の場合、コントローラーの作成/破棄のトリガーは何ですか?

以下の例を考えてみましょう:

var demoApp = angular.module('demo')
  .config(function($routeProvider, $locationProvider) {
    $routeProvider
      .when('/home', {templateUrl: '/home.html', controller: 'HomeCtrl'})
      .when('/users',{templateUrl: '/users.html', controller: 'UsersCtrl'})
      .when('/users/:userId', {templateUrl: '/userEditor.html', controller: 'UserEditorCtrl'});
  });

demoApp.controller('UserEditorCtrl', function($scope, $routeParams, UserResource) {
  $scope.user = UserResource.get({id: $routeParams.userId});
});

例えば:

上記の例では、に移動すると/users/1、user 1がロードされ、に設定されます$scope

次に、に移動すると/users/2、ユーザー2が読み込まれます。同じインスタンスがUserEditorCtrl再利用されていますか、それとも新しいインスタンスが作成されていますか?

  • それが新しいインスタンスである場合、最初のインスタンスの破棄をトリガーするものは何ですか?
  • 再利用する場合、これはどのように機能しますか?(つまり、データをロードするメソッドは、コントローラーの作成時に実行されているように見えます)

回答:


227

さて、実際の問題は、ngViewコントローラーのライフサイクルは何ですか。

コントローラはシングルトンではありません。誰でも新しいコントローラーを作成でき、自動破壊されることはありません。事実は、それが一般的にその基礎となるスコープのライフサイクルに結びついているということです。スコープが破棄されても、コントローラーは自動的に破棄されません。ただし、基になるスコープを破棄すると、そのコントローラーは役に立たなくなります(少なくとも、設計上はそうなるはずです)。

特定の質問に答えると、ngViewディレクティブ(およびngControllerディレクティブ)は、ナビゲーションが発生するたびに常に新しいコントローラーと新しいスコープを作成します。そして最後のスコープは破壊されますれます。

ライフサイクルの「イベント」は非常に単純です。あなたの「作成イベントは、」あなたのコントローラ自体の建設です。コードを実行するだけです。いつ役に立たなくなるかを知るには("破壊イベント")、スコープ$destroyイベントをリッスンします。

$scope.$on('$destroy', function iVeBeenDismissed() {
  // say goodbye to your controller here
  // release resources, cancel request...
})

ngView具体的には、コンテンツがスコープイベントを通じてロードされたときに知ることができます$viewContentLoaded

$scope.$on('$viewContentLoaded', function readyToTrick() {
  // say hello to your new content here
  // BUT NEVER TOUCHES THE DOM FROM A CONTROLLER
});

これは、コンセプトの証明が付いたPlunkerです(コンソールウィンドウを開きます)。


10
現在、$ scopeを破壊するコードはgithub.com/angular/angular.js/blob/…にあります。とても助かります、ありがとう!
w00t 2013年

4
viewContentLoadedは、テンプレートがロードされる直前にディスパッチされるため、タイムアウトを使用する場合にのみ機能します...ドキュメントは反対ですが、template: "HTML STRING"非同期にロードされるテンプレートファイルの場合はrawを参照しています。
user3338098 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.