J'ai un service AngularJS que je veux initialiser avec des données asynchrones. Quelque chose comme ça:
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();
}
};
});
Évidemment, cela ne fonctionnera pas parce que si quelque chose essaie d'appeler doStuff()
avant myData
revient, j'obtiendrai une exception de pointeur nul. Autant que je sache en lisant certaines des autres questions posées ici et ici, j'ai quelques options, mais aucune ne semble très propre (peut-être que je manque quelque chose):
Service d'installation avec "exécuter"
Lors de la configuration de mon application, procédez comme suit:
myApp.run(function ($http, MyService) {
$http.get('data.json').success(function (data) {
MyService.setData(data);
});
});
Ensuite, mon service ressemblerait à ceci:
myModule.service('MyService', function() {
var myData = null;
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
Cela fonctionne parfois, mais si les données asynchrones prennent plus de temps qu'il n'en faut pour que tout soit initialisé, j'obtiens une exception de pointeur nul lorsque j'appelle doStuff()
Utilisez des objets de promesse
Cela fonctionnerait probablement. Le seul inconvénient partout où j'appelle MyService, je devrai savoir que doStuff () renvoie une promesse et tout le code devra nous then
interagir avec la promesse. Je préfère simplement attendre que mes données soient de retour avant de charger mon application.
Bootstrap manuel
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 Je pourrais envoyer mon JSON directement à une variable Javascript globale:
HTML:
<script type="text/javascript" src="data.js"></script>
data.js:
var dataForMyService = {
// myData here
};
Il serait alors disponible lors de l'initialisation MyService
:
myModule.service('MyService', function() {
var myData = dataForMyService;
return {
doStuff: function () {
return myData.getSomeData();
}
};
});
Cela fonctionnerait aussi, mais j'ai une variable javascript globale qui sent mauvais.
Ce sont mes seules options? L'une de ces options est-elle meilleure que les autres? Je sais que c'est une question assez longue, mais je voulais montrer que j'ai essayé d'explorer toutes mes options. Tout conseil serait grandement apprécié.
$http
, puis enregistre les données dans un service, puis amorce une application.