Qual è il ciclo di vita di un controller AngularJS?


199

Qualcuno può chiarire qual è il ciclo di vita di un controller AngularJS?

  • Un controller è un singleton o creato / distrutto su richiesta?
  • In quest'ultimo caso, cosa provoca la creazione / distruzione del controller?

Considera l'esempio seguente:

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});
});

per esempio:

Nell'esempio sopra, quando navigo verso /users/1, l'utente 1 viene caricato e impostato su $scope.

Quindi, quando navigo verso /users/2, viene caricato l'utente 2. La stessa istanza di UserEditorCtrlriutilizzo o viene creata una nuova istanza?

  • Se si tratta di una nuova istanza, cosa provoca la distruzione della prima istanza?
  • Se viene riutilizzato, come funziona? (ad es., il metodo per caricare i dati sembra funzionare alla creazione del controller)

Risposte:


227

Bene, in realtà la domanda è qual è il ciclo di vita di un ngViewcontroller.

I controller non sono singoli. Chiunque può creare un nuovo controller e non vengono mai distrutti automaticamente. Il fatto è che è generalmente legato al ciclo di vita del suo ambito sottostante. Il controller non viene automaticamente distrutto ogni volta che il suo ambito viene distrutto. Tuttavia, dopo aver distrutto un ambito sottostante, il suo controller è inutile (almeno, in base alla progettazione, dovrebbe essere).

Rispondendo alla tua domanda specifica, una ngViewdirettiva (e anche una ngControllerdirettiva) creerà sempre un nuovo controller e un nuovo ambito ogni volta che si verifica una navigazione. E anche l' ultimo ambito verrà distrutto .

Gli "eventi" del ciclo di vita sono abbastanza semplici. Il tuo "evento di creazione" è la costruzione del controller stesso. Esegui il tuo codice. Per sapere quando diventa inutile ( "evento di distruzione" ), ascolta l' $destroyevento scope :

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

In ngViewparticolare, è possibile sapere quando il contenuto viene caricato tramite l'evento scope $viewContentLoaded:

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

Ecco un Plunker con un concept proof (apri la finestra della tua console).


10
Oggi il codice che distrugge $ scope vive su github.com/angular/angular.js/blob/… . Molto utile, grazie!
w00t

4
viewContentLoaded funziona solo se si utilizza un timeout perché viene inviato appena prima che il modello venga caricato ... i documenti dicono il contrario, ma si riferiscono a raw template: "HTML STRING"quando si tratta di un file modello che viene caricato in modo asincrono.
user3338098
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.