2015-08-10 15 views
6

Sto utilizzando ui-router v0.2.13. This page afferma che:Perché le funzioni di risoluzione dello stato figlio vengono eseguite prima che vengano risolte le promesse dello stato genitore

Tutto si risolve in uno Stato sarà risolto prima di passare al stato successivo, anche se non vengono iniettate in quel bambino

E più

Tutte le risoluzioni per tutti gli stati immessi vengono attivate e risolve prima che la transizione inserisca qualsiasi stato (indipendentemente da la risoluzione venga iniettata da qualche parte)

Tuttavia, nel mio caso, la funzione di risoluzione stato figlio viene eseguita prima che venga risolta la promessa di risoluzione del genitore. Com'è possibile?

Qui:

$stateProvider 
    .state('route1', { 
     url: "/route1", 
     templateUrl: "route1.html", 
     resolve: { 
      parent: ["$timeout", "$q", function ($timeout, $q) { 
       var d = $q.defer(); 
       $timeout(function() { 
        d.resolve(); 
       }, 5000); 
       return d.promise; 
      }] 
     } 
    }) 
    .state('route1.list', { 
     url: "/list", 
     templateUrl: "route1.list.html", 
     controller: function ($scope) { 
      $scope.items = ["A", "List", "Of", "Items"]; 
     }, 
     resolve: { 
      child: function() { 
       alert("I'm shown before `parent` resolved"); 
      } 
     } 
    }); 

Se navigare a /route1/list l'avviso viene immediatamente visualizzata invece di aspettare 5 secondi fino a una promessa genitore determinazione è stato risolto.

+1

Questa domanda potrebbe essere più semplice da rispondere se mostri del codice che riproduce il comportamento che stai descrivendo. – gilly3

+0

La funzionalità è abbastanza grande per aggiungerla a plunker o qualcosa del genere, volevo solo confermare che la mia comprensione delle virgolette sia corretta, vero? –

+0

Risoluzione dei genitori eseguita prima, potresti voler mostrare del codice :). La seconda citazione indica solo che lo stato del router verrà modificato dopo la risoluzione del problema. – Eloims

risposta

3

Tutti risolve sono garantiti da risolvere prima transizione è effettivamente svolto. Ma le dichiarazioni non indicano che le funzioni di risoluzione saranno chiamate in modo sincrono. E questo è corretto.

In base allo ui-routersource code, gli invocabili sono risolti il ​​più possibile "paralleli". Solo quelli dipendenti da altri invocabili (dai genitori o dalla dichiarazione dello stato attuale) saranno eseguiti dopo la risoluzione delle loro dipendenze.

Quindi l'unico modo per fare child invocabile da richiamare dopo parent è stato risolto è quello di specificare parent come dipendenza del child invocabile.

.state("route1",{ 
    //.. 
    resolve: { 
     parent: ["$timeout", "$q", function ($timeout, $q) { 
      var d = $q.defer(); 
      $timeout(function() { 
       d.resolve(); 
      }, 5000); 
      return d.promise; 
     }] 
    } 
}) 
.state("route1.list",{ 
    //... 
    resolve: { 
     child: ["parent", function(parent) { 
      //will be called only after parent is resolved 
     }] 
}) 

Estratto dalle commenti del codice sorgente GitHub resolve.js:

Invocables sono invocati con entusiasmo non appena tutte le dipendenze sono disponibili. Ciò vale anche per le dipendenze ereditate da una chiamata parent a $resolve.

+1

Questa è un'ottima risposta. Si noti che in ui-router 1.0, le risoluzioni avranno 3 opzioni di politica: "EAGER" (come comportamento di risoluzione corrente), "LAZY" e "JIT". Le risoluzioni pigre vengono richiamate appena prima che venga inserito lo stato su cui sono dichiarate (questo è il comportamento che assume il richiedente la domanda). Le Risoluzioni JIT non vengono invocate fino a quando qualcos'altro le inietta. –

2

Quindi, ciò che sta effettivamente accadendo è che poiché non si sta iniettando "genitore" nelle rotte figlio risolte, non attenderà il genitore prima di tentare di risolvere il figlio. Se si tenta questo:

resolve: { 
    child: function(parent) { 
    alert("Child Resolved!"); 
    } 
} 

quindi di risolvere sarà chiamato dopo il timeout (risolvere) del genitore il bambino.

Credo che ciò che significa il doc sia che attenderà tutto risolto prima di eseguire la transizione effettiva allo stato, ad esempio il caricamento del controller e il rendering dei modelli.

Nel plunker sottostante (che per lo più ho preso in prestito da un vecchio esempio di scotch.io) ho giocato spostando le dipendenze. Se la risoluzione del bambino dipende da una risoluzione genitore, la promessa del genitore viene risolta prima del bambino. Se il bambino non dipende, il bambino risolve prima (anche se la durata del timeout è impostata su 0).

In tutti i casi, tuttavia, i controllori padre e figlio non vengono immessi e le viste non vengono visualizzate finché sia ​​il figlio sia il genitore sono entrambi risolti.

http://plnkr.co/edit/EtU03AfgUAlWNsEH0TuU?p=preview

+0

Grazie, il tuo presupposto _Credo cosa significa il documento è che attenderà tutto risolto prima di eseguire la transizione effettiva allo stato come il caricamento del controller e il rendering dei modelli ._ è ciò che può davvero essere ciò che dice il doc. Penso che aspetterò ancora un po 'prima di accettare la risposta, forse qualcuno apparirà chi lo sa per certo. Ho upvoted la tua risposta. –

Problemi correlati