Tôi có một dịch vụ AngularJS mà tôi muốn khởi tạo với một số dữ liệu không đồng bộ. Một cái gì đó như thế này:
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();
}
};
});
Rõ ràng điều này sẽ không hoạt động bởi vì nếu có gì đó cố gắng gọi doStuff()
trước khi myData
quay lại, tôi sẽ nhận được một ngoại lệ con trỏ null. Theo như tôi có thể nói khi đọc một số câu hỏi khác được hỏi ở đây và ở đây tôi có một vài lựa chọn, nhưng không ai trong số chúng có vẻ rất sạch sẽ (có lẽ tôi đang thiếu một cái gì đó):
Dịch vụ cài đặt với "chạy"
Khi thiết lập ứng dụng của tôi, hãy làm điều này:
myApp.run(function ($http, MyService) {
$http.get('data.json').success(function (data) {
MyService.setData(data);
});
});
Sau đó, dịch vụ của tôi sẽ như thế này:
myModule.service('MyService', function() {
var myData = null;
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
Điều này hoạt động đôi khi nhưng nếu dữ liệu không đồng bộ xảy ra mất nhiều thời gian hơn mọi thứ để được khởi tạo, tôi sẽ nhận được một ngoại lệ con trỏ null khi tôi gọi doStuff()
Sử dụng các đối tượng hứa
Điều này có thể sẽ làm việc. Nhược điểm duy nhất ở mọi nơi tôi gọi MyService tôi sẽ phải biết rằng doStuff () trả lại một lời hứa và tất cả các mã sẽ phải để chúng tôi then
tương tác với lời hứa. Tôi chỉ muốn đợi cho đến khi myData trở lại trước khi tải ứng dụng của tôi.
Hướng dẫn sử dụng 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 Tôi có thể gửi JSON của mình trực tiếp đến một biến Javascript toàn cầu:
HTML:
<script type="text/javascript" src="data.js"></script>
data.js:
var dataForMyService = {
// myData here
};
Sau đó, nó sẽ có sẵn khi khởi tạo MyService
:
myModule.service('MyService', function() {
var myData = dataForMyService;
return {
doStuff: function () {
return myData.getSomeData();
}
};
});
Điều này cũng hoạt động, nhưng sau đó tôi có một biến javascript toàn cầu có mùi khó chịu.
Đây có phải là lựa chọn duy nhất của tôi? Là một trong những lựa chọn tốt hơn so với những người khác? Tôi biết đây là một câu hỏi khá dài, nhưng tôi muốn chứng tỏ rằng tôi đã cố gắng khám phá tất cả các lựa chọn của mình. Bất kỳ hướng dẫn sẽ rất được đánh giá cao.
$http
, sau đó lưu dữ liệu trong dịch vụ, sau đó khởi động ứng dụng.