从服务返回值时,控制器的 $scope 变量未定义
$scope variable of a controller is undefined when returning values from a service
AngularJS 这里是新手。我正在尝试使用服务从 Google 端点获取结果。我启动了 Google API 并且 execute() return 得到了正确的结果。但是,当我尝试将此结果 return 传递给控制器中的 $scope 变量时, $scope 变量仍未定义。
服务中的函数如下所示:
app.service('gapiService',function(){
var getSubjectList=function(){
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
console.log("resp "+resp.items); //this prints the proper result
return resp.items;
}
});
};
return{
getSubjectList:getSubjectList
};
});
调用服务中函数的控制器中的函数如下所示:
var getSubjectList=function(){
$scope.subj=gapiService.getSubjectList();
console.log($scope.subj); //this is undefined
}
此外,控制器中的 console.log() 在服务中的 console.log() 之前打印。所以我尝试使用 promise 并像这样更改服务:
var getSubjectList=function(){
var p=$q.defer();
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
console.log("resp "+resp.items);
return resp.items;
}
});
return p.promise;
};
即便如此,我也没有 resp.items 进入我的 $scope.subj。我确定我以错误的方式使用了承诺。还是有其他问题?
你必须调用 resolve 和 reject on p.
var getSubjectList=function(){
var p=$q.defer();
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
console.log("resp "+resp.items);
p.resolve(resp.items);
}
p.reject('error');
});
return p.promise;
};
试试这个...
你确实是错误地使用了promise。 API 函数 returns 带有回调,调用回调时需要 resolve promise。应按以下方式完成:
var getSubjectList=function(){
var p=$q.defer();
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
console.log("resp "+resp.items);
p.resolve(resp.items);
}
p.reject();
});
return p.promise;
};
您使用承诺中的 "then" 函数来获取已解决的承诺:
var getSubjectList=function(){
gapiService.getSubjectList().then(function(result){
$scope.subj=result;
console.log($scope.subj);
});
}
那是绝对自然的。 Promises 只是一种让 javascript 异步代码看起来更好的方法 ;) 所以即使使用它们,你仍然必须尊重异步逻辑。
让我解释一下:
当您在控制器中调用 getSubjectList
时,它将执行 gapiService.getSubjectList()
,这将调用 gapi.client.subjectendpoint.listSubject().execute()
但请注意,您在服务中登录到控制台的函数是回调,以便稍后在当前控制器的代码完成后调用它。
这就是控制器在您的服务回调之前继续执行和记录的原因。
另一点是,当你使用 promise 时,你必须 resolve
或 reject
(如果失败)它们并且你的服务代码应该如下所示:
var getSubjectList = function () {
var deferred = $q.defer();
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
deferred.resolve(resp.items);
}
else {
deferred.reject("OH MY GOD! SOMETHING WENT WRONG!")
}
});
return deferred.promise;
};
你的控制器代码应该是:
var getSubjectList=function(){
gapiService.getSubjectList().then(function (items) {
$scope.subj = items;
});
}
如您所见,现在它是异步的,因为使用 then
,您正在等待解决承诺,以便调用将值设置到范围内的回调。
顺便说一下,AngularJS 可以绑定 "promises" 而不仅仅是值。
因此,您可以使用:
$scope.subj = gapiService.getSubjectList();
如果您尝试 console.log($scope.subj)
,它只会向您显示尚未包含该值的承诺,但如果您像这样在模板中使用它:
<ul ng-repeat="item in $scope.subj">
<li ng-bind="item"></li>
</ul>
Angular 将监视承诺直到它被解决然后使用已解决的值。
不要忘记使用 promise.catch
处理错误和类似的事情
和 promise.finally
.
为了性能起见,如果您的值一旦设置就不会更改,请使用 AngularJS 1.3 的一次性绑定。
<ul ng-repeat="item in ::$scope.subj">
<li ng-bind="::item"></li>
</ul>
我们在博客上写了一篇关于此的文章www.blog.wishtack.com
AngularJS 这里是新手。我正在尝试使用服务从 Google 端点获取结果。我启动了 Google API 并且 execute() return 得到了正确的结果。但是,当我尝试将此结果 return 传递给控制器中的 $scope 变量时, $scope 变量仍未定义。
服务中的函数如下所示:
app.service('gapiService',function(){
var getSubjectList=function(){
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
console.log("resp "+resp.items); //this prints the proper result
return resp.items;
}
});
};
return{
getSubjectList:getSubjectList
};
});
调用服务中函数的控制器中的函数如下所示:
var getSubjectList=function(){
$scope.subj=gapiService.getSubjectList();
console.log($scope.subj); //this is undefined
}
此外,控制器中的 console.log() 在服务中的 console.log() 之前打印。所以我尝试使用 promise 并像这样更改服务:
var getSubjectList=function(){
var p=$q.defer();
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
console.log("resp "+resp.items);
return resp.items;
}
});
return p.promise;
};
即便如此,我也没有 resp.items 进入我的 $scope.subj。我确定我以错误的方式使用了承诺。还是有其他问题?
你必须调用 resolve 和 reject on p.
var getSubjectList=function(){
var p=$q.defer();
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
console.log("resp "+resp.items);
p.resolve(resp.items);
}
p.reject('error');
});
return p.promise;
};
试试这个...
你确实是错误地使用了promise。 API 函数 returns 带有回调,调用回调时需要 resolve promise。应按以下方式完成:
var getSubjectList=function(){
var p=$q.defer();
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
console.log("resp "+resp.items);
p.resolve(resp.items);
}
p.reject();
});
return p.promise;
};
您使用承诺中的 "then" 函数来获取已解决的承诺:
var getSubjectList=function(){
gapiService.getSubjectList().then(function(result){
$scope.subj=result;
console.log($scope.subj);
});
}
那是绝对自然的。 Promises 只是一种让 javascript 异步代码看起来更好的方法 ;) 所以即使使用它们,你仍然必须尊重异步逻辑。
让我解释一下:
当您在控制器中调用 getSubjectList
时,它将执行 gapiService.getSubjectList()
,这将调用 gapi.client.subjectendpoint.listSubject().execute()
但请注意,您在服务中登录到控制台的函数是回调,以便稍后在当前控制器的代码完成后调用它。
这就是控制器在您的服务回调之前继续执行和记录的原因。
另一点是,当你使用 promise 时,你必须 resolve
或 reject
(如果失败)它们并且你的服务代码应该如下所示:
var getSubjectList = function () {
var deferred = $q.defer();
gapi.client.subjectendpoint.listSubject().execute(function(resp){
if(!resp.code){
deferred.resolve(resp.items);
}
else {
deferred.reject("OH MY GOD! SOMETHING WENT WRONG!")
}
});
return deferred.promise;
};
你的控制器代码应该是:
var getSubjectList=function(){
gapiService.getSubjectList().then(function (items) {
$scope.subj = items;
});
}
如您所见,现在它是异步的,因为使用 then
,您正在等待解决承诺,以便调用将值设置到范围内的回调。
顺便说一下,AngularJS 可以绑定 "promises" 而不仅仅是值。
因此,您可以使用:
$scope.subj = gapiService.getSubjectList();
如果您尝试 console.log($scope.subj)
,它只会向您显示尚未包含该值的承诺,但如果您像这样在模板中使用它:
<ul ng-repeat="item in $scope.subj">
<li ng-bind="item"></li>
</ul>
Angular 将监视承诺直到它被解决然后使用已解决的值。
不要忘记使用 promise.catch
处理错误和类似的事情
和 promise.finally
.
为了性能起见,如果您的值一旦设置就不会更改,请使用 AngularJS 1.3 的一次性绑定。
<ul ng-repeat="item in ::$scope.subj">
<li ng-bind="::item"></li>
</ul>
我们在博客上写了一篇关于此的文章www.blog.wishtack.com