AngularJS : 返回 .then() 对控制器的响应 属性

AngularJS : Returning .then() response to controller property

我正在使用工厂检索数据,使用 $httpcontrollerAs 功能注入到我的视图中。如果不使用 $scope,我在将 $http 响应数据返回到控制器中的 属性 时遇到问题。

我的工厂

myApp.factory('Topics', function ($http, $q) {
    var service = {},
        _error = 'Oh no! Something went wrong. Please check back later.';


    service.getTopics = function () {
        var deferred = $q.defer();

        $http.get(_url).success(function (resp) {
            deferred.resolve(resp);
        }).error (function () {
            deferred.reject(_error);
        });
        return deferred.promise;
    }

    return service;
});

我的控制器

 myApp.controller('TopicsCtrl', function (Topics) {
    this.topics = (function () {
        return Topics.getTopics().then(function (resp) {
            console.log(resp);
            return resp;
        });
    })();
}

我的观点

<h1>{{ top.topics }}</h1>

就像我说的,我在配置为 top 的路线中使用 controllerAs。控制器中的 console.log 记录了我正在寻找的内容,但 topics 的值在注入视图时为空。留给我 {}。

P.S。据我了解 $http$q 的抽象,这让我想知道是否不需要在此示例中使用 $q

以下应该有效:

  myApp.controller('TopicsCtrl', function (Topics) {
    Topics.getTopics().then(function (resp) {
      this.topics = resp;
    }.bind(this));
  });

然后通过 top.topics 在您的视图中访问它。

编辑:另外,您在服务中不需要 $q 是正确的。您可以直接 return $http.get:

service.getTopics = function() {
    return $http.get(_url);
};

您所做的是用承诺初始化 top.topics。但是 angular views 不能对 promises 做任何事情。他们需要的是实际数据,当承诺得到解决时可以访问。所以你需要的是:

// oh the joys of this...
var that = this;

Topics.getTopics().then(function (resp) {
    console.log(resp);
    that.topics = resp;
});

请注意,您可以在服务中使用承诺链:

    return $http.get(_url).then(function (resp) {
        return resp.data;
    }).catch(function() {
        return $q.reject(_error);
    });