在解决不同的promise之后解决将要扩展的对象的正确方法

时间:2015-10-24 00:54:48

标签: javascript angularjs angular-ui-router restangular

我正在尝试将资源分页器作为 restangular 的包装服务:

.factory('Collection', Collection)
 function Collection(Restangular) {
    var _route;
    ...

    function Collection(collectionName) {
        if (typeof collectionName === "undefined") {
            throw new Error("collection name is missing");
        }
        _route = collectionName;
    };

    Collection.prototype = {

        setData: function(response) {
            var data = response.data.plain();
            var _links = helpers.parse_link_header(response.headers('Link'));
            ...

            angular.extend(this, data);
        },

        load: function(perPage) {
            var scope = this;
            Restangular.all(_route).getList({'page':1, 'per-page':perPage})
            .then(function(collectionData) {
                scope.setData(collectionData);
            });
        },

        firstPage: function() {...},
        nextPage: function() {...}),
        ...

这就是我在控制器中使用它的方式:

vm.images = new Collection('images');
vm.images.load(2);

images.load()将从服务器获取数据,一旦解析,它将发送给setData()方法,该方法将执行我需要的所有逻辑,因为解析标题链接,元,...然后将扩展类我期望在我的控制器中拥有的所有数据。

这很有效。它会在页面加载时抛出几个逻辑错误,例如Cannot read property 'next' of undefined,但是一旦模型扩展,一切正常,我可以在 HTML视图文件中执行这些操作

vm.images.nextPage();
vm.images.existNext();
vm.images.meta().$currentPage;

我的问题是:

在ui-router的状态解析方法中初始化 my collection 的正确方法是什么,并确保在实例化控制器之前我的对象是通过服务器响应进行扩展的?

到目前为止我尝试了什么:

我知道应该以某种方式返回 promise ,所以我使load方法看起来像:

load: function(perPage) {
    var deferred = $q.defer();
    var scope = this;
    _perPage = perPage;
    Restangular.all(_route).getList({'page':1, 'per-page':perPage})
    .then(function(collectionData) {
        var e = scope.setData(collectionData)
        deferred.resolve(e);
    }, 
    function(response) {
      console.log("Error with status code", response.status);
      deferred.reject();
    });
    return deferred.promise;
},

我做了setData返回somthing:

setData: function(response) {
    ...
    var newClass = angular.extend(this, data);
    return newClass;
},

然后我将其添加到我的 $ stateProvider.state

resolve: {
  Collection: 'Collection',
  images: function(Collection){
    var images = new Collection('images');
    images.load(2);
    return images; 
  }
},
控制器内的

vm.images = images正在按预期获取数据,但是相同的错误与没有添加它的情况相同,因此其中的代码正在执行,但我无法弄清楚如何让它等待要通过服务器响应扩展的模型。

任何帮助都将受到赞赏&提前谢谢!

1 个答案:

答案 0 :(得分:1)

在解析器中,您应该返回 load 承诺:

images: function (Collection){
    var images = new Collection('images');
    return images.load(2);
}

另请注意,在load函数中,您可以使用getList返回的承诺:

load: function (perPage) {
    return Restangular.all(_route).getList({'page':1, 'per-page':perPage})
        .then(scope.setData)
        .catch(function (response) {
            return $q.reject('Error with status code ' + response.status);
        });
}