У меня есть служба 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
вернется, я получу исключение нулевого указателя. Насколько я могу судить по прочтению некоторых других вопросов, заданных здесь и здесь, у меня есть несколько вариантов, но ни один из них не кажется очень чистым (возможно, я что-то упускаю):
Настройка службы с помощью «Выполнить»
При настройке моего приложения сделайте это:
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, которая плохо пахнет.
Это мои единственные варианты? Один из этих вариантов лучше, чем другие? Я знаю, что это довольно длинный вопрос, но я хотел показать, что я попытался изучить все мои варианты. Любое руководство будет с благодарностью.
$http
, затем сохранение данных в службе, а затем загрузка приложения.