Một nơi nào đó bạn sẽ cần phải "chờ đợi".
duy nhất được xây dựng theo cách trong góc để hoàn toàn giải oan khiển từ phải chờ ngày của riêng mình cho dữ liệu async được nạp là để nhanh chóng một bộ điều khiển với tài sản resolve
$routeProvider
's đường (hoặc thay thế $stateProvider
của ui.router
) . Điều này sẽ chạy bộ điều khiển chỉ khi tất cả các lời hứa được giải quyết, và dữ liệu được giải quyết sẽ được tiêm.
Vì vậy, ng-đường thay thế - plunker:
$routeProvider.when("/", {
controller: "SomeCtrl",
templateUrl: "someTemplate.html",
resolve: {
settings: function(settingsSvc){
return settingsSvc.load(); // I renamed the loading function for clarity
}
});
Sau đó, trong SomeCtrl
bạn có thể thêm settings
như một sự phụ thuộc tiêm:
.controller("SomeCtrl", function($scope, settings){
if (settings.foo) $scope.bar = "foo is on";
})
này sẽ "chờ" để tải someTemplate
trong <div ng-view></div>
cho đến khi cài đặt được giải quyết.
Các settingsSvc
nên bộ nhớ cache lời hứa để nó sẽ không cần phải thực hiện lại các yêu cầu HTTP. Lưu ý, mà như đã đề cập trong câu trả lời khác, không có nhu cầu $q.defer
khi API bạn đang sử dụng (như $http
) đã trả về một lời hứa:
.factory("settingsSvc", function($http){
var svc = {settings: {}};
var promise = $http.get('/api/public/settings/get').success(function(data){
svc.settings = data; // optionally set the settings data here
});
svc.load = function(){
return promise;
}
});
Một cách tiếp cận, nếu bạn không thích những ngRoute
, có thể là để phát sóng dịch vụ settings
trên $rootScope
một sự kiện khi cài đặt được tải và bộ điều khiển có thể phản ứng với nó và làm bất cứ điều gì. Nhưng điều đó có vẻ "nặng hơn" .then
.
Tôi đoán cách thứ ba-plunker - sẽ có một bộ điều khiển ứng dụng cấp "cho phép" phần còn lại của ứng dụng chỉ khi tất cả các phụ thuộc đã cài đặt sẵn:
.controller("AppCtrl", function($q, settingsSvc, someOtherService){
$scope.loaded = false;
$q.all([settingsSvc.load, someOtherService.prefetch]).then(function(){
$scope.loaded = true;
});
});
Và trong Xem , chuyển đổi ng-if
với loaded
:
<body ng-controller="AppCtrl">
<div ng-if="!loaded">loading app...</div>
<div ng-if="loaded">
<div ng-controller="MainCtrl"></div>
<div ng-controller="MenuCtrl"></div>
</div>
</body>
Như tôi đã viết, tôi muốn tránh phần "settings.then". Lý tưởng nhất là tôi muốn bộ điều khiển SomeCtrl đợi cho đến khi cài đặt được tải. Điều đó có thể không? –
bạn cần phải giải quyết nó bằng cách chỉ $ xem trong trường hợp đó trên $ rootScope.settings nhưng đó không phải là thực hành tốt (vấn đề permormance) kiểm tra bẩn và chu kỳ tiêu hóa mới sẽ làm chậm sự hoàn hảo. – squiroid
Cảm ơn bạn đã chia sẻ phản hồi này. Đây là điều tuyệt vời cho tôi để làm cho chức năng dịch vụ của tôi tốt hơn và sạch hơn. – racl101