【问题标题】:Angular.js resourceProvider returns $promise with dataAngularjs 资源提供者返回 $promise 和数据
【发布时间】:2014-11-25 03:37:29
【问题描述】:

给定 angular.js 服务:

angular.module('mymodule').factory('Products', ['$resource',
    function($resource) {
        return $resource('/path/to/getProducts', {}, {
            find: {
                method: 'GET',
                isArray: false
            }
        });
    }
]);

mymodule的控制器里我做find查询:

$scope.findAll = function () {
    Products.find(function (products) {
        console.log(Object.keys(products));
        // ['prodA', 'prodB', ... , '$promise', '$resolved']
        for (var i in products) {
            if (!products.hasOwnProperty(i)) continue;
            console.log(products[i].description.someprop);
            // Got error: Cannot read property 'someprop' of undefined
            // Trust me: I debug this place. someprop is defined for all items except that two
        }
    });
};

它工作正常,但返回 $promise 和 $resolved 数据集,所以我不能遍历我的数据。

Angular 文档 says 表明 Resource 实例和集合具有这些附加属性。但我不明白如何在我的代码中控制它。

我做错了什么?如何预防?

【问题讨论】:

    标签: javascript angularjs rest angular-services resourceproviderfactory


    【解决方案1】:

    确实,当您不使用数组时,它会稍微复杂一些。

    服务器发回的response对象包含:

    • resource 对象(您的数据 + $promise$resolved,这就是您在回调中得到的)
    • 一个config 对象(标头、使用的方法、调用的url 等)和一个headers 函数
    • 和一个data 对象,这就是我们想要的!它只包含数据。

    但您只能在then() 中看到response.resource。因此,您需要拦截服务器发送的响应来获取数据:

    return $resource('/path/to/getProducts', {}, {
            find: {
               method: 'GET',
               isArray: false,
               interceptor: {
                 response: function(response) {  
                   return response.data;
                 }
               }
            }
        });
    

    然后在你的控制器中:

    Products.find().$promise.then(
        function(products){
            angular.forEach(products, function(value, index){
                console.log(value);
            });
        }
    );
    

    告诉我这是否适合你。

    Plunker Demo

    【讨论】:

    • 谢谢!这就是我需要的
    • stackoverflow 不允许我现在奖励你的答案,但我会在 20 小时内完成)
    • @deonclem 有没有办法将此响应拦截器设置为所有 $resource 的默认行为?对所有这些重复此代码似乎不正确。
    • 检查文档:docs.angularjs.org/api/ng/service/$http 在“拦截器”部分下。这将拦截您进行的每个$http 调用(因为$resource 使用$http)。如果只想拦截特定的调用,可以试试:stackoverflow.com/questions/23021416/…
    【解决方案2】:

    资源返回一个promise,你可以使用then()从promise中检索数据。

    Products.find().$promise.then(function (products) {
        console.log(Object.keys(products));
    });
    

    【讨论】:

    • 它们将是,因为它返回一个承诺......你仍然可以循环你的收藏。阅读promises
    • 我遇到了错误。如果我使用简单的 for 循环而不是 ng-repeat 循环,这有关系吗?用代码更新了我的问题
    【解决方案3】:

    我猜你的问题是'isArray: false'。所以你的产品不是一个数组,而是一个对象。设置 'isArray: true' 你可以整天迭代 for(var product in products)。

    【讨论】:

    • 我的产品不是数组而是对象,所以我将 isArray 设置为 false。如果 isArray 设置为 true 但后端返回 object angular throws errow Error: [$resource:badcfg] 所以我不能这样做
    【解决方案4】:

    尝试做 response.toJSON,它只返回你的 json,不包括 promise 和 resolve。

    data.$promise.then(function(myResponse) {
        var actualData = myResponse.toJSON();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 2018-10-19
      • 2013-07-05
      • 1970-01-01
      相关资源
      最近更新 更多