Angularjs call asynchronous before page renders
仅记录下最近学到的一点angular js 知识。 业务描述前情说明最近在做一个angularjs的相关项目,需要在page render之前调用后台的restapi 获取到用户名user,用该值去设置某些service并用于前端页面渲染(全部页面渲染之前必须得到user),并且在app.run 中要inject的一些service(例如项目中item.js定义的Item service) 也需要获取到user。 解决方案要点1 - promisespromises在angularjs中是通过$q来提供的。 angular.module('myApp')
.config(function($httpProvider){
$httpProvider.defaults.headers.common['Content-Type'] = 'application/json;charset=utf-8';
})
.service('Data',function ($q,$http) {
this.getUser() = function(){
return getUrl('xxxx');
};
//define getUrl method
var getUrl = function(url,timeout) {
var defferred = $q().defer;
var opts = {
method:'GET',url:url
};
if(timeout)
opts.timeout = timeout;
$http(opts)
.success(function(result,status,headers){
//do some handling
deferred.resolve(result);
})
.error(function(error){
// do some error handling
deferred.reject(xxx);
});
return deferred.promise;
};//end of getUrl
});//end of service
为了获取a,定义了一个单独的service User in user.js. angular.module('myApp')
.service('User',function(Data,$rootScope,otherService) {
//this is the default locale.
var DEFAULT_VALUE = 'Guest';
this.getUser = function () {
var promise = Data.getUser().then(
function(result){ // fetch succeed
$rootScope.user = result;
},function(result){ //fetch failed.
$rootScope.user = DEFAULT_VALUE ;
}
).finally(
function(){
otherService.setxxxx($routScope.user);//if need to set.
}
);
};
});
要点2 - resolve of $routeProviderpromise 解决了获取到值后的回调问题,仍需要其他方法来保证在页面加载前能够完成回调函数的执行。 resolve定义
global resolve但是因为router 配置的比较多,每个router都要设置相同的resolve,会比较麻烦,所以通过修改$routeProvider的 when函数定义,来达到简化代码的目的。 angular
.module('myApp',[
'ngRoute'
//....etc
])
.config(function ($routeProvider) {
// can't add service in the argument since config only support provider
//define universal resolve for all routes
var globalResolve = {
'user' : function(User){ // User service as argument
return User.getUser();
}
};
// extend routeProvider to have a global resolve
var originWhen = $routeProvider.when;
$routeProvider.when = function(path,route){
route.resolve = route.resolve || (route.resolve = {});
angular.extend(route.resolve,globalResolve);
return originWhen.call($routeProvider,path,route);
};
$routeProvider
.when('/',{
templateUrl: 'views/main.html',controller: 'MainCtrl'
})
//....etc routers
});
要点3 app.run 和 resolve的 promise回调执行顺序在项目中有以下定义: app.run(function ($rootScope,$location,Data,Time,$timeout,Item) {
//do something
});
其中Item service的定义中用到了 user值,因此会出现问题。 有更好的方法的话,希望可以留言教一下我咯~ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |