我正在尝试从工厂到控制器的响应。但是当我从控制器调用工厂的功能时,控制器不等待它的响应。并给予" undefined"。
这是我的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方法下面执行。并且由于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;
});
}
};
答案 0 :(得分:2)
最好使用$ q模块处理角度异步函数。阅读本文档:
答案 1 :(得分:1)
这样做:
在工厂
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属性的最佳方式答案 2 :(得分:1)
您正在执行异步请求,问题是您在定义数据之前检索数据。
一个好的做法是使用承诺。您需要知道 $ http 服务返回承诺,并且有一些回调方法,例如.success()
和.then()
。
对于诺言,angular为我们提供了一个非常好的工具: $ 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>
您可以看到Working Plunker
答案 3 :(得分:0)
在$scope
函数中写下您的所有then
变量。
所以 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;
});