我正在使用承诺从我的服务中的json获取数据,然后将其传递给我的控制器。我遇到了一些问题。
这是我的服务
getMetaData: function () {
var defer = this.$q.defer();
this.$http.get('http://localhost:8084/login-api/public/metadata/describe/Coisa')
.success(function (data, status, headers, config) {
defer.resolve(data)
})
.error(function (data, status, headers, config) {
defer.reject(status);
})
return defer.promise;
}
在这里,我将服务称为我的控制器
getData: function () {
this.$scope.meta = this.EntityService.getMetaData();
var dataS = {};
this.$scope.meta.then(
function (data) {
this.$scope.metaD = data;
},
function (err) {
alert('Error');
}
)
}
这就是我遇到的错误:
TypeError: Cannot set property 'metaD' of undefined
at basic-list-controller.js:29
at l.promise.then.l (angular.js:7)
at angular.js:7
at u.$get.u.$eval (angular.js:7)
at u.$get.u.$digest (angular.js:7)
at u.$get.u.$apply (angular.js:7)
at p (angular.js:7)
at T (angular.js:7)
at XMLHttpRequest.b.onreadystatechange (angular.js:7)
我不知道为什么我有这个错误。当我在控制台上记录数据时,它就在那里,但我无法将值赋给变量。
答案 0 :(得分:1)
在你的成功功能"这个"不是你所期待的
function (data) {
this.$scope.metaD = data;
}
你可以尝试在回调之外设置这个:
var _this = this;
并在你的回调中使用:
function (data) {
this.$scope.metaD = data;
}
您的最终代码应如下所示:
getData: function () {
var _this = this;
this.$scope.meta = this.EntityService.getMetaData();
var dataS = {};
this.$scope.meta.then(
function (data) {
_this.$scope.metaD = data;
},
function (err) {
alert('Error');
}
)
}
答案 1 :(得分:1)
你如何解决这个问题有很多问题。
首先:您不需要将$q.defer
用于已经返回承诺的内容,例如$http
- 这被视为deferred anti-pattern
第二:避免将$scope
传递给您的服务 - 这使得测试和消除关注点分离变得更加困难。 $scope
属于控制器。
因此,您的服务可以变得更加简单。你甚至不需要两种方法 - 因为两者都返回相同的东西
.factory("myDataService", function($http){
return {
getMetaData: function(){
return $http.get('url/to/data');
}
};
}
.controller("MainCtrl", function($scope, myDataService){
myDataService.getMetaData()
.then(function(data)){
$scope.metaD = data;
});
}
答案 2 :(得分:0)
你可以简化它,因为使用$ http服务可以直接返回一个promise并使用'then'函数在返回之前预处理数据:
getMetaData: function () {
return $http.get('http://localhost:8084/login-api/public/metadata/describe/Coisa')
.then(function (success) {
return success.data;
},
function (error) {
return error;
});
}
现在应该可以使用其余的代码了。注意我返回整个结果,如果你只想要响应然后返回'succes.data'。或者你可以在控制器代码上检查它。