scope e controller di istanza con router ui

Sono confuso su quando i controllori vengono istanziati. Inoltre, in che modo i controllori vengono istanziati quando si annidano gli stati. Potrei essere confuso su come l’ambito viene collegato alla vista e al controller, cioè se ogni vista ottiene il proprio controllore e l’ambito o condivide lo stesso ambito.

Qualcuno può spiegare quando i controllori vengono istanziati? Sotto i percorsi nidificati tutte le viste condividono un controller e un ambito? Cosa succede quando cambio stato e ritorno a uno stato viene triggersto un altro controller?

Di seguito sono riportati i miei percorsi (file di configurazione):

.config (googleAnalyticsCordovaProvider, $stateProvider, $urlRouterProvider, IdleProvider, KeepaliveProvider) -> $stateProvider .state('app', { url: '/app', abstract: true, templateUrl: 'templates/menu.html', controller: 'AppController' }) .state('app.pincode', { url: '/pincode', views: { menuContent: { templateUrl: 'templates/pincode-yield.html', controller: 'PincodeController' } } }) .state('app.pincode.create', { url: '/create', views: { pincode: { templateUrl: 'templates/pincode-create.html', controller: 'PincodeController' } } }) .state('app.pincode.pincodeLogin', { url: '/login', views: { pincode: { templateUrl: 'templates/pincode-login.html', controller: 'PincodeController' } } }) .state('app.pincode.settings', { url: '/settings', views: { pincode: { templateUrl: 'templates/settings.html', controller: 'PincodeController' } } }) 

Per ottenere risposte ancora più dettagliate, possiamo / dovremmo osservare il codice sorgente e controllare la documentazione . Lasciatemi provare a spiegare tutte e tre le domande (e anche citare codice e doc).

1. Quando i controllori vengono istanziati?

Qui possiamo osservare il codice della direttiva ui-view :

[$ViewDirective.$inject = \['$state', '$injector', '$uiViewScroll', '$interpolate'\];][1]

I controller sono correlati alle visualizzazioni . Quelle views , che sono definite all’interno di .state() come object views :

 .state('...', { // The view definition views : { '' : { template: ... controller: ... resolve: .. } }, resolve: ... } 

Quindi, ogni volta che la vista (la vista ui-view ) è piena di impostazioni definite all’interno di una vista di stato, agisce quasi come una direttiva standard, ma migliorata .

1) Il modello è stato trovato,
2) Le risoluzioni sono risolte

x) Il controller è istanziato …

Visualizza obiettivi (direttive ui-view ) potrebbero usare nomi e potrebbero essere riempiti da diversi stati nella gerarchia.

Potrebbe significare che potrebbe esserci un contenuto all’interno di una vista (ad es. Titolo ) , definito dal genitore e sostituito dal bambino

 // parent .state('parent', { views : { '' : {...} // the main parent view, with ui-view="title" '[email protected]' : { ...} // here we go and fill parent's ui-view="title" }, ... } // child .state('parent.child', { views : { 'title' : { ...} // here we change the parent's target ui-view="title" }, ... } 

La definizione di cui sopra sarà (ogni volta che passeremo tra questi due stati) :

  • $state.go('parent') – la vista (template, controller …) definita in '[email protected]' : { ...} sarà iniettata in target ui-view="title" e istanziata come descritto sopra

  • $state.go('parent.child') – quasi lo stesso, solo la vista verrà presa da child state / view defintion 'title' : { ...} . Questo sostituirà il contenuto di ui-view="title" e sarà istanziato come descritto sopra

Questo avverrà ogni volta che passeremo da un genitore a un bambino e da un bambino all’altro .

2. Sotto i percorsi nidificati tutte le viste condividono un controller e un ambito?

Una risposta semplice è NO , non c’è condivisione comune.

In effetti, ogni controller ha il proprio ambito , quello creato dall’ambito di visualizzazione padre. Innanzitutto la documentazione:

Che cosa gli Stati figli ereditano dagli Stati genitori?

Ereditarietà dell’ambito solo per visualizzazione gerarchia

Tenere presente che le proprietà dell’ambito ereditano solo la catena di stato se le viste dei propri stati sono nidificate. L’ereditarietà delle proprietà dell’ambito non ha nulla a che fare con l’annidamento dei tuoi stati e tutto ciò che riguarda l’annidamento delle tue visualizzazioni (modelli).

È del tutto ansible che tu abbia stati nidificati i cui modelli popolano le visualizzazioni ui in varie posizioni non nidificate all’interno del tuo sito. In questo scenario non ci si può aspettare di accedere alle variabili dell’ambito delle viste dello stato genitore all’interno delle viste degli stati figli.

Quindi, ogni volta che il nostro controller (bene la vista con template, controller …) viene iniettato nel target del genitore ui-view="..." ottiene l’ambito ereditato:

 newScope = scope.$new(); 

Questo in poche parole significa che gli oggetti JS (es. scope.Model = {} ) possono essere condivisi tra figlio e genitore.

 $scope.Model.id = 1; // will refer to the same id in both parent & child 

Tuttavia , i tipi di Javascript di base non vengono passati per riferimento e pertanto i loro valori non vengono sincronizzati automaticamente tra gli ambiti:

 // set in parent $scope.id = 1; // in child after inherted still === 1 $scope.id = 2; // now 2 for a child, different value in parent - still === 1 

Vale la pena leggere di più sull’eredità prototipica qui:
Quali sono le sfumature dell’eredità prototipo / prototipo dell’oscilloscopio in AngularJS?

3. Cosa succede quando cambio stato e ritorno a uno stato: viene istanziato un altro controller?

Dipende.

Se la vista secondaria genitore (ricorda ui-view="title" sopra) viene sostituita dalla vista figlio, e quindi viene ricreata (passaggio da figlio a genitore) – tale controller verrà reinizializzato (discusso sopra).

Ma quando parliamo della vista principale genitore (solitamente senza nome) , che rappresenta il genitore (per esempio la vista senza nome sotto con il controllore “ParentMainCtrl”)

 .state('parent', { views : { '' : { // // the main parent view controller: 'ParentMainCtrl', } '[email protected]' '[email protected]' }, 

Quindi possiamo essere sicuri che tale controller NON sia nuovamente istanziato. Vive durante la vita di tutti i suoi figli, più quello di un genitore (nessuno stato figlio selezionato) .

Per ricaricare questa vista / controller, dobbiamo usare un’opzione di reload

$ state.go (a, parametri, opzioni)

… opzioni Opzioni object. Le opzioni sono:

  • ricarica{boolean=false} , Se true imporrà la transizione anche se lo stato oi parametri non sono stati modificati, ovvero un ricaricamento dello stesso stato. Differisce da reloadOnSearch perché lo utilizzeresti quando vuoi forzare una ricarica quando tutto è lo stesso, inclusi i parametri di ricerca.

Spero che aiuti un po ‘. Per ulteriori informazioni, consulta queste risorse:

  • Stati nidificati e viste nidificate
  • Più viste con nome
  • Riferimento API
  • State.js dell’applicazione di esempio – direi la parte di codice documentata migliore di sempre

I controllori vengono istanziati ogni volta che si visita lo stato specifico. Ad esempio, mentre visiti app.pincode.pincodeLogin per la prima volta, vengono AppController un AppController e due PincodeControllers , ciascuno con la propria vista, assumendo che tu abbia i modelli giusti. Passare a 'app.pincode.settings' distruggerebbe il controller più interno e sostituirlo con uno nuovo, anche se i due controller più in alto nella gerarchia non verranno toccati. Gli ambiti seguono lo schema di ereditarietà standard di AngularJS, non sono isolati.

Probabilmente vorresti rimuovere i controller negli stati secondari (e gestire la logica di business nel controller principale) o disporre di un controller distinto per ogni stato: lo stesso controller per diversi modelli e visualizzazioni è in genere un segno di progettazione errata.

I controllori vengono istanziati quando le viste corrispondenti vengono caricate per la prima volta.

Ad esempio, se si dispone di 3 tabs associate a 3 controller, il controller associato alla vista predefinita istanzia Primo. Successivamente, quando si caricano le altre viste, anche i controllori associati vengono istanziati.

Ma interessante, una volta che una vista viene caricata nel DOM, viene memorizzata per impostazione predefinita. Quando una vista viene allontanata da, il suo elemento viene lasciato nel DOM e il suo ambito viene disconnesso dal ciclo $ watch. Quando si naviga verso una vista che è già stata memorizzata nella cache, il suo ambito viene quindi ricollegato e l’elemento esistente lasciato nel DOM diventa la vista triggers.