AngularJS中的promise错误

Error in promises in AngularJS

本文关键字:错误 promise 中的 AngularJS      更新时间:2023-09-26

我使用promise从服务中的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)

我不明白为什么我会犯这个错误。当我在控制台上记录数据时,它就在那里,但我不能给变量赋值。

处理此问题的方法有很多错误。

第一:对于已经返回promise的东西,如$http,不需要使用$q.defer,这被认为是延迟反模式。

第二:避免将$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;
      });
}

在你的成功函数中,"这"不是你所期望的

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');
                }
        )
    }

您可以将其简化为这样,因为使用$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;
                    });
        }

现在,这应该可以与代码的其余部分一起使用了。注意,我会返回整个结果,如果你只想要响应,那么返回"success.data"。或者你可以在控制器代码中检查它。