[英]How to make the controller wait for factory response in angularjs?
我试图从工厂到控制器的响应。 但是,当我从控制器调用工厂函数时,则控制器不等待其响应。 并给出“未定义”。
这是我的controller.js
app.controller('customerCommentsController',function($scope,$http,$stateParams,$sce,$timeout,Comments){
var commentsdata = '';
Comments.init(1,5);
$scope.total_comments = Comments.total();
console.log($scope.total_comments); //undefined
$scope.positive_comments = Comments.positive();
console.log($scope.positive_comments); //undefined
$scope.commentsdata = Comments.getcomments(1,30);
console.log($scope.commentsdata); //undefined
});
在这里,我正在调用init()方法,该方法从ajax获取响应,这需要花费一些时间来执行,但在此方法完成之前,另外2条语句(total()和positive()方法)在init方法下执行。 由于初始化方法未完成,因此无法初始化。 那就是为什么我变得不确定。 当我调用不等待其响应的getcomments方法时,也会出现相同的问题。
这是我的工厂
app.factory("Comments",function($http,$timeout,$q){
var commentshtml = [];
var commentshtml1 = [];
return {
init : function(start,end) {
var request = $http({
method:"post",
url:"/comments.php",
data: {start:start,end:end},
headers: {'Content-Type' : 'application/x-www-form-urlencoded'}
});
request.success(function(data){
commentshtml = data;
});
},
total : function() {
return commentshtml.total_comment;
},
positive : function(){
return commentshtml.per_positive_comment;
},
getcomments : function(start,end) {
var promise = $http({
method:"post",
url:"/comments.php",
data: {start:start,end:end},
headers: {'Content-Type' : 'application/x-www-form-urlencoded'}
});
promise.success(function(data){
commentshtml1 = data.comments;
console.log(commentshtml1); //giving the object
return commentshtml1;
});
}
};
最好使用$ q模块与angular中的异步函数一起使用。 阅读此文档:
这样做:
在工厂
return {
init : function(start,end) {
return $http({ //return the promise
method:"post",
url:"/comments.php",
data: {start:start,end:end},
headers: {'Content-Type' : 'application/x-www-form-urlencoded'}
});
}
getcomments : function(start,end) {
return $http({ //return the promise
method:"post",
url:"/comments.php",
data: {start:start,end:end},
headers: {'Content-Type' : 'application/x-www-form-urlencoded'}
});
}
在控制器中
Comments.init(1,5).then(function(){
$scope.total_comments = Comments.total();
console.log($scope.total_comments);
$scope.positive_comments = Comments.positive();
console.log($scope.positive_comments);
});
Comments.getcomments(1,30).then(function(data){
$scope.commentsdata =data.comments;
})
或者是在ng-route或ui-router中使用resolve属性的最佳方法
您正在执行异步请求,问题是您在定义数据之前先检索数据。
一个好的做法是使用诺言 。 你脑水肿知道,$ http服务回报承诺,并有一定的回调方法,如.success()
和.then()
的例子。
为了保证,角度为我们提供了一个很好的工具: $ q.defer() 。
$ q.defer()是来自延迟API的承诺管理器 。
$q.defer()
得到2种方法:
resolve(value)
:通过赋予她最终的价值来解决我们相关的承诺
reject(reason)
:解决承诺错误。
因此,您可以执行以下操作:
调节器
(function(){
function Controller($scope, Comments) {
//Retrieve our init promise
var promise_init = Comments.init();
//Retrieve our total promise
var promise_total = Comments.total();
promise_init.then(function(){
//Return promise for chaining
return promise_total;
}).then(function(total){
//Retrieve total of comments
$scope.total = total;
}).catch(function(err){
//Catch error of total comments
$scope.total = err;
});
}
angular
.module('app', [])
.controller('ctrl', Controller);
})();
服务
(function(){
function Service($q){
var commentshtml = [];
function init(){
//Create defer object
var defer = $q.defer();
commentshtml = ['a', 'b', 'c'];
//Simulate latency
setTimeout(function(){
//Resolve our promise
defer.resolve();
}, 2000);
//Return a promise
return defer.promise;
}
function total(){
var defer = $q.defer();
commentshtml.length < 3
? defer.reject('error length')
: defer.resolve(commentshtml.length);
return defer.promise;
}
return {
init: init,
total: total
};
}
angular
.module('app')
.factory('Comments', Service);
})();
HTML
<body ng-app='app' ng-controller='ctrl'>
<h2>Total : {{total}}</h2>
</body>
您可以看到工作柱塞
在then
函数中编写所有$scope
变量。
所以你的Controller.js :
app.controller('customerCommentsController',function($scope,$http,$stateParams,$sce,$timeout,Comments){
var commentsdata = '';
Comments.init(1,5).then(function(){
$scope.total_comments = Comments.total();
console.log($scope.total_comments); //undefined
$scope.positive_comments = Comments.positive();
console.log($scope.positive_comments); //undefined
$scope.commentsdata = Comments.getcomments(1,30);
console.log($scope.commentsdata); //undefined
}
});
您必须返回$http
请求。
因此,您的init函数如下所示:
init : function(start,end) {
return $http({
method:"post",
url:"/comments.php",
data: {start:start,end:end},
headers: {'Content-Type' : 'application/x-www-form-urlencoded'}
}).success(function(data){
return commentshtml = data;
});
}
还有你的工厂:
app.factory("Comments",function($http,$timeout,$q){
var commentshtml = [];
var commentshtml1 = [];
return {
init : function(start,end) {
return $http({
method:"post",
url:"/comments.php",
data: {start:start,end:end},
headers: {'Content-Type' : 'application/x-www-form-urlencoded'}
}).success(function(data){
return commentshtml = data;
});
},
total : function() {
return commentshtml.total_comment;
},
positive : function(){
return commentshtml.per_positive_comment;
},
getcomments : function(start,end) {
var promise = $http({
method:"post",
url:"/comments.php",
data: {start:start,end:end},
headers: {'Content-Type' : 'application/x-www-form-urlencoded'}
});
promise.success(function(data){
commentshtml1 = data.comments;
console.log(commentshtml1); //giving the object
return commentshtml1;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.