У мене є служба 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
});
});
Global 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
, потім зберегти дані в сервісі, потім завантажити додаток.