2013-04-18 16 views
188

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

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

consideri il seguente esempio:

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

es:

Nell'esempio precedente, quando naviga verso /users/1, utente 1 viene caricato e impostato sul $scope.

Quindi, quando si passa a /users/2, viene caricato l'utente 2. È stata riutilizzata la stessa istanza di UserEditorCtrl oppure è stata creata una nuova istanza?

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

risposta

212

Bene, in realtà la domanda è qual è il ciclo di vita per un controller ngView.

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

rispondere alla tua domanda specifica, una direttiva ngView (anche per ngController direttiva) sarà sempre create a new controller and a new scope ogni volta una navigazione accade. E lo last scope is going to be destroyed pure.

Gli "eventi" del ciclo di vita sono piuttosto semplici. L'evento di creazione "" è la costruzione del controller stesso. Esegui il tuo codice. Per sapere quando si arriva inutile ("evento di distruzione"), ascoltare la portata $destroy evento:

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

Per ngView specificamente, si è in grado di sapere quando il contenuto viene caricato tramite l'evento portata $viewContentLoaded:

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

Here is a Plunker con una prova di concetto (aprire la finestra della console).

+10

Al giorno d'oggi il codice che distrugge l'ambito $ vive in https://github.com/angular/angular.js/blob/65f5e856a161e7c91b9ebde1360242dc704d0510/src/ngRoute/directive/ngView.js#L179. Molto utile, grazie! – w00t

+2

viewContentLoaded funziona solo se si utilizza un timeout perché viene inviato appena prima del caricamento del modello ... i documenti dicono il contrario, ma si riferiscono al modello 'grezzo:" HTML STRING "' quando si tratta di un file modello che viene caricato asincrono come. – user3338098

Problemi correlati