How to prevent AngularJS from displaying the view until the Ajax request has been completed (页面延迟问题)
$routeProvider resolve propertyallows delaying of route change until data is loaded.
原来在controller中直接ajax直接获取数据:
$http.get(dataUrl)
.success(function(data){ //直接获取数据库,会有延迟,在route 配置中 控制 数据resolve,在将数据传入页面$scope
$scope.data.products=data;
//console.log($scope.data.products);
}).error(function (error) {
$scope.data.error = error;
});
现在 把 取数据 放在resolve 中,再将已经获取的数据传入controller中,即:
app.config(['$routeProvider', function($routeProvider) {
//$locationProvider.html5Mode(true);
$routeProvider
.when("/products", {
templateUrl: "views/productList.html",
controller:'productsShowDelay',
resolve:{
products: ["ProductsLoader", function(ProductsLoader) {
return ProductsLoader();//因为factory为 return function
}]
}
}).when(..).otherwise(..)
.controller('productsShowDelay',['$scope','products',function($scope,products){
$scope.data.products=products;
}])
service.js中配置:
app.factory("productsResource",['$resource','dataUrl',function($resource,dataUrl){
return $resource(dataUrl);
}])
.factory('ProductsLoader', ['productsResource', '$q',function(productsResource,$q){
return function(){
var delay=$q.defer();
productsResource.query(function(ProductsData){
//console.log(ProductsData);
delay.resolve(ProductsData);
},function(errData){
delay.reject(); // you could optionally pass error data here
});
return delay.promise;
};
}]);
下为 overstack 相同问题的解决方法:
$routeProvider resolve property allows delaying of route change until data is loaded.
First define a route with resolve attribute like this.
angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: PhoneListCtrl,
resolve: PhoneListCtrl.resolve}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: PhoneDetailCtrl,
resolve: PhoneDetailCtrl.resolve}).
otherwise({redirectTo: '/phones'});
}]);
notice that the
resolve
property is defined on route.
function PhoneListCtrl($scope, phones) {
$scope.phones = phones;
$scope.orderProp = 'age';
}
PhoneListCtrl.resolve = {
phones: function(Phone, $q) {
var deferred = $q.defer();
Phone.query(function(successData) {
deferred.resolve(successData);
}, function(errorData) {
deferred.reject(); // you could optionally pass error data here
});
return deferred.promise;
},
delay: function($q, $defer) {
var delay = $q.defer();
$defer(delay.resolve, 1000);
return delay.promise;
}
}
Notice that the controller definition contains a resolve object which declares things which should be available to the controller constructor. Here the phones is injected into the controller and it is defined in the resolve property.
The resolve.phones function is responsible for returning a promise. All of the promises are collected and the route change is delayed until after all of the promises are resolved.
上文中 $defer为 angular 1.0.0中 服务,后续版本用 $timeout服务 代替了$defer,
$timeout(function(){
deferred.resolve(ProductsData);
},2000)
本文介绍如何使用AngularJS的$routeProvider resolve属性来延迟路由更改,直到数据加载完成。通过示例代码展示了如何在控制器中使用resolve属性来确保视图显示前已完成Ajax请求。
1110

被折叠的 条评论
为什么被折叠?



