Каков жизненный цикл контроллера 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, пользователь 1 загружается и устанавливается на $scope.

Затем, когда я перехожу на /users/2, пользователь 2 загружается. Один и тот же экземпляр UserEditorCtrlиспользуется повторно, или создан новый экземпляр?

  • Если это новый экземпляр, что вызывает уничтожение первого экземпляра?
  • Если он используется повторно, как это работает? (т.е. способ загрузки данных запускается при создании контроллера)

Ответы:


227

Ну, на самом деле вопрос в том, каков жизненный цикл ngViewконтроллера.

Контроллеры не синглтоны. Каждый может создать новый контроллер, и он никогда не будет автоматически уничтожен. Дело в том, что он, как правило, связан с жизненным циклом своей основной области. Контроллер не уничтожается автоматически всякий раз, когда его область действия уничтожается. Однако после разрушения основной области видимости его контроллер становится бесполезным (по крайней мере, по замыслу, так и должно быть).

Отвечая на ваш конкретный вопрос, ngViewдиректива (также для ngControllerдирективы) всегда будет создавать новый контроллер и новую область видимости каждый раз, когда происходит навигация. И последний прицел тоже будет уничтожен .

Жизненный цикл «событий» довольно прост. Ваше «событие создания» - это конструкция самого вашего контроллера. Просто запустите свой код. Чтобы узнать, когда он становится бесполезным ( «событие разрушения» ), прослушайте $destroyсобытие scope :

$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
В настоящее время код, который уничтожает область видимости $, находится по адресу github.com/angular/angular.js/blob/… . Очень полезно, спасибо!
w00t

4
viewContentLoaded работает, только если вы используете тайм-аут, потому что он отправляется непосредственно перед загрузкой шаблона ... документы говорят об обратном, но они ссылаются на raw, template: "HTML STRING"когда это файл шаблона, он загружается асинхронно.
user3338098
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.