2012-09-10 14 views
15

Vorrei ritardare l'inizializzazione di un controller finché non sono arrivati ​​i dati necessari dal server.Inizializzazione del controller di ritardo Angular.js

ho trovato questa soluzione per 1.0.1 Angolare: Delaying AngularJS route change until model loaded to prevent flicker, ma non poteva farlo funzionare con angolare 1.1.0

Template

<script type="text/ng-template" id="/editor-tpl.html"> 
Editor Template {{datasets}} 
</script> 
    <div ng-view> 
</div> 

JavaScript

function MyCtrl($scope) {  
    $scope.datasets = "initial value"; 
} 

MyCtrl.resolve = { 
    datasets : function($q, $http, $location) { 
     var deferred = $q.defer(); 

     //use setTimeout instead of $http.get to simulate waiting for reply from server 
     setTimeout(function(){ 
      console.log("whatever"); 
      deferred.resolve("updated value"); 
     }, 2000); 

     return deferred.promise; 
    } 
}; 

var myApp = angular.module('myApp', [], function($routeProvider) { 
    $routeProvider.when('/', { 
     templateUrl: '/editor-tpl.html', 
     controller: MyCtrl, 
     resolve: MyCtrl.resolve 
    }); 
});​ 

http://jsfiddle.net/dTJ9N/1/

risposta

11

Da $ http restituisce una promessa, è un calo di prestazioni per creare il proprio differita solo di restituire la promessa, quando arriva il dato http. Si dovrebbe essere in grado di fare:

MyCtrl.resolve = { 
    datasets: function ($http) { 
     return $http({method: 'GET', url: '/someUrl'}); 
    } 
}; 

Se avete bisogno di fare un po 'di elaborazione del risultato, utilizzare .poi, e la promessa è incatenato in gratuitamente:

MyCtrl.resolve = { 
    datasets: function ($http) { 
     return $http({method: 'GET', url: '/someUrl'}) 
       .then (function (data) { 
        return frob (data); 
       }); 
    } 
}; 
+0

Esempio di lavoro: http://jsfiddle.net/dTJ9N/5 – mb21

+10

Direi che il colpo di performance per aver avvolto la promessa di $ http con un'altra promessa in questo caso è così piccolo che non vale la pena preoccuparsi. Tuttavia, il codice più conciso derivante dall'esclusione della promessa extra è un degno perseguimento. –

+0

Il codice è bello e pulito, ma ad oggi, il violino è rotto, mostra la fonte del documento. Troppo nuovo per Angular per essere di grande aiuto oltre a ciò. – enigment

1

È possibile dare un'occhiata a un quasi identica domanda here che utilizza le risorse, ma funziona allo stesso modo con $ http. Penso che questo dovrebbe funzionare

function MyCtrl($scope, datasets) {  
    $scope.datasets = datasets; 
} 

MyCtrl.resolve = { 
    datasets: function($http, $q) { 
     var deferred = $q.defer(); 

     $http({method: 'GET', url: '/someUrl'}) 
      .success(function(data) { 
       deferred.resolve(data) 
     } 

     return deferred.promise; 
    } 
}; 

var myApp = angular.module('myApp', [], function($routeProvider) { 
    $routeProvider.when('/', { 
     templateUrl: '/editor-tpl.html', 
     controller: MyCtrl, 
     resolve: MyCtrl.resolve 
    }); 
});​ 
+0

Grazie, corretto un errore di sintassi o due, qui il codice di lavoro: http://jsfiddle.net/dTJ9N/2/ – mb21

4

si può sempre e solo mettere "ng-show" sull'elemento DOM più esterno e impostalo uguale ai dati che si desidera attendere.

Per l'esempio indicato sulla home page angolare JS si può vedere come è facile: http://plnkr.co/CQu8QB94Ra687IK6KgHn Tutto ciò che doveva essere fatto è stato In questo modo il modulo non mostrerà fino a quando è stato impostato il valore.

Molto più intuitivo e meno lavoro in questo modo.

+0

e se si hanno più carichi di dati? non sai quale finirà mentre tutti corrono asyn. Ad esempio ... suppongo di aver bisogno delle 5 opzioni da mostrare in una casella di selezione e di tutti i dati relativi alla prima opzione, quindi posso precaricare il modulo ??? – Jason

+0

Se ne hai cinque, nessun problema, dopo che ognuno carica, prendi nota e una volta che tutti e cinque sono stati soddisfatti. Devi solo avere una variabile con un array e controllare che la lunghezza sia 5 dopo ogni aggiunta di carico di dati e dopo 5 impostare un'altra variabile su cui ng-show si basa e resettare il tuo array di conteggio. – stormlifter

Problemi correlati