Tengo un servicio AngularJS que quiero inicializar con algunos datos asincrónicos. Algo como esto:
myModule.service('MyService', function($http) {
var myData = null;
$http.get('data.json').success(function (data) {
myData = data;
});
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
Obviamente, esto no funcionará porque si algo intenta llamar doStuff()
antes de que myData
vuelva, obtendré una excepción de puntero nulo. Por lo que puedo decir al leer algunas de las otras preguntas formuladas aquí y aquí , tengo algunas opciones, pero ninguna de ellas parece muy limpia (tal vez me falta algo):
Servicio de configuración con "ejecutar"
Al configurar mi aplicación, haga esto:
myApp.run(function ($http, MyService) {
$http.get('data.json').success(function (data) {
MyService.setData(data);
});
});
Entonces mi servicio se vería así:
myModule.service('MyService', function() {
var myData = null;
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
Esto funciona algunas veces, pero si los datos asíncronos tardan más de lo que se tarda en inicializar todo, obtengo una excepción de puntero nulo cuando llamo doStuff()
Usa objetos de promesa
Esto probablemente funcionaría. El único inconveniente en todas partes que llamo MyService tendrá que saber que doStuff () devuelve una promesa y todo el código nos tendrá then
que interactuar con la promesa. Prefiero esperar hasta que myData regrese antes de cargar mi aplicación.
Bootstrap manual
angular.element(document).ready(function() {
$.getJSON("data.json", function (data) {
// can't initialize the data here because the service doesn't exist yet
angular.bootstrap(document);
// too late to initialize here because something may have already
// tried to call doStuff() and would have got a null pointer exception
});
});
Global Javascript Var Podría enviar mi JSON directamente a una variable global de Javascript:
HTML:
<script type="text/javascript" src="data.js"></script>
data.js:
var dataForMyService = {
// myData here
};
Entonces estaría disponible al inicializar MyService
:
myModule.service('MyService', function() {
var myData = dataForMyService;
return {
doStuff: function () {
return myData.getSomeData();
}
};
});
Esto también funcionaría, pero luego tengo una variable global de JavaScript que huele mal.
¿Son estas mis únicas opciones? ¿Una de estas opciones es mejor que las otras? Sé que esta es una pregunta bastante larga, pero quería mostrar que he tratado de explorar todas mis opciones. Cualquier orientación sería muy apreciada.
$http
, luego guardar datos en un servicio y luego arrancar una aplicación.