Mam usługę AngularJS, którą chcę zainicjować za pomocą niektórych danych asynchronicznych. Coś takiego:
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();
}
};
});
Oczywiście to nie zadziała, ponieważ jeśli coś spróbuje zadzwonić doStuff()
przed myData
powrotem, otrzymam wyjątek wskaźnika zerowego. O ile mogę stwierdzić po przeczytaniu niektórych innych pytań zadanych tutaj i tutaj mam kilka opcji, ale żadne z nich nie wydaje się bardzo czyste (być może czegoś mi brakuje):
Usługa instalacyjna z „uruchom”
Podczas konfigurowania mojej aplikacji wykonaj następujące czynności:
myApp.run(function ($http, MyService) {
$http.get('data.json').success(function (data) {
MyService.setData(data);
});
});
Wtedy moja usługa wyglądałaby tak:
myModule.service('MyService', function() {
var myData = null;
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
Działa to czasami, ale jeśli dane asynchroniczne zdarzają się dłużej niż potrzeba, aby wszystko zostało zainicjowane, otrzymuję wyjątek wskaźnika zerowego podczas wywoływania doStuff()
Użyj obiektów obietnicy
To prawdopodobnie zadziałałoby. Jedynym minusem jest to, że wszędzie, gdzie nazywam MyService, będę musiał wiedzieć, że doStuff () zwraca obietnicę i cały kod będzie musiał do nas wejść then
w interakcję z obietnicą. Wolę poczekać, aż myData wróci przed załadowaniem mojej aplikacji.
Ręczny pasek startowy
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 Mógłbym wysłać mój JSON bezpośrednio do globalnej zmiennej JavaScript:
HTML:
<script type="text/javascript" src="data.js"></script>
data.js:
var dataForMyService = {
// myData here
};
Wtedy byłby dostępny przy inicjalizacji MyService
:
myModule.service('MyService', function() {
var myData = dataForMyService;
return {
doStuff: function () {
return myData.getSomeData();
}
};
});
To też by działało, ale mam globalną zmienną javascript, która źle pachnie.
Czy to moje jedyne opcje? Czy jedna z tych opcji jest lepsza od innych? Wiem, że to dość długie pytanie, ale chciałem pokazać, że próbowałem zbadać wszystkie moje opcje. Wszelkie wskazówki będą mile widziane.
$http
, a następnie zapisać dane w usłudze, a następnie uruchomić aplikację.