2012-09-10 35 views
15

Me gustaría retrasar la inicialización de un controlador hasta que los datos necesarios hayan llegado del servidor.Angular.js que retrasa la inicialización del controlador

He encontrado esta solución para 1.0.1 Angular: Delaying AngularJS route change until model loaded to prevent flicker, pero no pude conseguir que el trabajo con la plantilla angular 1.1.0

<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/

Respuesta

11

Desde $ http devuelve una promesa, es un impacto en el rendimiento para crear su propio diferido sólo para devolver la promesa cuando los datos http llega. Usted debe ser capaz de hacer:

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

Si necesita hacer algo de procesamiento del resultado, utilice .then, y su promesa es encadenado en forma gratuita:

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

Ejemplo de trabajo: http://jsfiddle.net/dTJ9N/5 – mb21

+10

Yo diría que el El rendimiento alcanzado para cumplir la promesa de $ http con otra promesa en este caso es tan pequeño que no vale la pena preocuparse por ello. Sin embargo, el código más conciso resultante de la exclusión de la promesa adicional es una actividad digna. –

+0

El código es agradable y limpio, pero a partir de hoy, el violín está roto, muestra el origen del documento. Demasiado nuevo en Angular para ser de mucha ayuda más allá de notar eso. – enigment

1

Puede echar un vistazo a una pregunta casi idéntica here que utiliza recursos, pero funciona de la misma manera con $ http. Creo que esto debería funcionar

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

Gracias, corrigió un error de sintaxis o dos, aquí el código de trabajo: http://jsfiddle.net/dTJ9N/2/ – mb21

4

siempre se puede simplemente poner "ng-show" en el elemento DOM más externo y establézcalo igual a los datos que desea esperar.

Para el ejemplo que aparece en la página principal de JS angular se puede ver lo fácil que es: http://plnkr.co/CQu8QB94Ra687IK6KgHn Todo lo que había que hacer era De esa manera la forma no se mostrará hasta que se haya establecido ese valor.

Mucho más intuitivo y menos trabajo de esta manera.

+0

¿Qué sucede si tiene múltiples cargas de datos? usted no sabe cuál terminará ya que todos corren asyn. Por ejemplo ... supongo que necesito las 5 opciones para mostrar en un cuadro de selección y todos los datos relativos a la primera opción, para que pueda precargar el formulario ??? – Jason

+0

Si tiene cinco, no hay problema, después de cada carga solo tome nota y una vez que los cinco terminen, sea feliz. Solo necesita tener alguna variable con una matriz y verificar que la longitud sea 5 después de que cada carga de datos lo agregue y después de 5 establecer otra variable en la que ng-show esté basado y reiniciar su matriz de conteo. – stormlifter

Cuestiones relacionadas