从服务返回值时$scope控制器的变量是未定义的
$scope variable of a controller is undefined when returning values from a service
AngularJS新手在这里。我正在尝试使用服务从谷歌端点获取结果。我已经启动了谷歌API,execute()返回正确的结果。但是当我尝试将此结果返回到控制器中的$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 中。我确定我以错误的方式使用了这个承诺。还是还有其他问题?
这是绝对自然的。承诺只是使javascript异步代码看起来更好的一种方式;)因此,即使使用它们,您仍然必须尊重异步逻辑。
让我解释一下:
当您在控制器中调用 getSubjectList
时,它将执行将调用gapi.client.subjectendpoint.listSubject().execute()
gapiService.getSubjectList()
但请注意,您在服务中登录到控制台的函数是回调,因此将在当前控制器的代码完成后稍后调用它。
这就是控制器在服务回调之前继续执行和记录的原因。
另一点是,当你使用承诺时,你必须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可以绑定"承诺",而不仅仅是价值。
因此,您可以使用:
$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
你必须在 p 上调用 resolve 和拒绝。
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;
};
试试这个...
你确实错误地使用了承诺。API 函数返回回调,调用回调时需要解析 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);
});
}
- Javascript变量未定义,onchange不起作用
- 定义的变量未定义
- 无法弄清楚为什么本机 Promise 变量未定义
- Windows 8 Javascript 疯狂 - 变量未定义
- $rootScope变量未定义
- 变量未定义
- Javascript:TypeError变量未定义
- 变量未定义/超出范围
- javascript变量未定义
- Javascript变量未定义错误
- $scope变量未定义,尽管它是在$watch函数内部设置的
- 类型错误:变量未定义
- AngularJs $http变量未定义
- JQuery:创建扩展返回变量未定义
- d3.js变量未定义,但在Firefox控制台中,它可以工作
- Javascript 中用于上传表单数据的变量未定义
- 节点.js模块级变量未定义
- Node.js req.session 变量未定义
- 错误:AngularJs 变量未定义,当使用 grunt 运行时.(泽泽尔)
- 将字符串拆分为两个变量 - 未定义不是一个函数