Ich habe einen AngularJS-Dienst, den ich mit asynchronen Daten initialisieren möchte. Etwas wie das:
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();
}
};
});
Offensichtlich funktioniert dies nicht, denn wenn etwas versucht aufzurufen, doStuff()
bevor es myData
zurückkommt, erhalte ich eine Nullzeigerausnahme. Soweit ich aus den anderen hier und hier gestellten Fragen ersehen kann , habe ich einige Optionen, aber keine davon scheint sehr sauber zu sein (vielleicht fehlt mir etwas):
Setup Service mit "run"
Gehen Sie beim Einrichten meiner App folgendermaßen vor:
myApp.run(function ($http, MyService) {
$http.get('data.json').success(function (data) {
MyService.setData(data);
});
});
Dann würde mein Service so aussehen:
myModule.service('MyService', function() {
var myData = null;
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
Dies funktioniert manchmal, aber wenn die asynchronen Daten länger dauern als es dauert, bis alles initialisiert ist, erhalte ich beim Aufruf eine Nullzeigerausnahme doStuff()
Verwenden Sie Versprechen Objekte
Das würde wahrscheinlich funktionieren. Der einzige Nachteil überall, wo ich MyService anrufe, ist, dass doStuff () ein Versprechen zurückgibt und der gesamte Code für die then
Interaktion mit dem Versprechen erforderlich ist . Ich würde lieber warten, bis myData zurück ist, bevor ich meine Anwendung lade.
Manueller Bootstrap
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 Ich könnte meinen JSON direkt an eine globale Javascript-Variable senden:
HTML:
<script type="text/javascript" src="data.js"></script>
data.js:
var dataForMyService = {
// myData here
};
Dann wäre es beim Initialisieren verfügbar MyService
:
myModule.service('MyService', function() {
var myData = dataForMyService;
return {
doStuff: function () {
return myData.getSomeData();
}
};
});
Das würde auch funktionieren, aber dann habe ich eine globale Javascript-Variable, die schlecht riecht.
Sind das meine einzigen Möglichkeiten? Ist eine dieser Optionen besser als die anderen? Ich weiß, dass dies eine ziemlich lange Frage ist, aber ich wollte zeigen, dass ich versucht habe, alle meine Optionen zu erkunden. Jede Anleitung wäre sehr dankbar.
$http
abzurufen, Daten in einem Dienst zu speichern und dann eine App zu booten.