У меня есть служба AngularJS, которую я хочу инициализировать с помощью некоторых асинхронных данных. Что-то вроде этого:
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();
}
};
});
Очевидно, что это не сработает, потому что если что-то пытается вызвать doStuff()
до того, как myData
вернется, я получу исключение нулевого указателя. Насколько я могу судить по чтению некоторых других вопросов, заданных здесь и здесь У меня есть несколько вариантов, но ни один из них не кажется очень чистым (возможно, я чего-то не хватает):
Служба настройки с "run"
При настройке моего приложения выполните следующие действия:
myApp.run(function ($http, MyService) {
$http.get('data.json').success(function (data) {
MyService.setData(data);
});
});
Тогда моя служба будет выглядеть так:
myModule.service('MyService', function() {
var myData = null;
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
Это работает некоторое время, но если асинхронные данные занимают больше времени, чем требуется, чтобы все инициализировалось, я получаю исключение с нулевым указателем, когда я вызываю doStuff()
Использовать объекты обещания
Это, вероятно, сработает. Единственный недостаток, который я везде называю MyService, должен знать, что doStuff() возвращает обещание, и весь код будет иметь для нас then
, чтобы взаимодействовать с обещанием. Я предпочел бы просто ждать, пока myData вернется, прежде чем загружать мое приложение.
Ручной бутстрап
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
});
});
Глобальный Javascript Var Я мог бы отправить свой JSON непосредственно в глобальную переменную Javascript:
HTML:
<script type="text/javascript" src="data.js"></script>
data.js:
var dataForMyService = {
// myData here
};
Тогда он будет доступен при инициализации MyService
:
myModule.service('MyService', function() {
var myData = dataForMyService;
return {
doStuff: function () {
return myData.getSomeData();
}
};
});
Это тоже сработает, но тогда у меня есть глобальная переменная javascript, которая плохо пахнет.
Являются ли эти мои единственные варианты? Являются ли одни из этих вариантов лучше других? Я знаю, что это довольно длинный вопрос, но я хотел показать, что я попытался изучить все мои варианты. Любое руководство будет очень оценено.