【问题标题】:Why does angular $resource add extra objects ($promise, $resolve...) to my data response?为什么 Angular $resource 会在我的数据响应中添加额外的对象($promise、$resolve...)?
【发布时间】:2017-11-03 17:05:50
【问题描述】:

我返回一个带有 URL 的资源

    $resource("http://foo.com/bar.json").get().
         $promise.then(function(data){ $scope.result = data}, 
                  function(error){ $scope.msg = "error" } );

资源回报

["item1"...."item_n",.....,"$promise", "$resolved", "$get", "$save", "$query", "$remove", "$delete"]

为什么我会在我的数据集中获得所有这些对象。我猜 $promise 只是返回所有这些并等待服务器响应。但是,一旦我获得了服务器响应,我在哪里可以获取没有 Promise 术语的服务器数据?

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    如果你看这里的角度源:

    https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js#L505

    资源原型链上有一个 toJSON 方法可以为您完成此任务。

    例如:

    $resource("http://foo.com/bar.json").get(function(res) {
        $scope.result = res.toJSON();
    });
    

    【讨论】:

    • 与@chovy 和@Tallboy 的问题相同。感觉很笨拙,但诉诸 JSON.parse(JSON.stringify(res)) 得到了很好的结果。
    • 这是一个糟糕的解决方案。将其转换为 JSON 字符串后,需要再次解析。最好的方法来自@callmejuggernaut stackoverflow.com/a/32313951/276949
    • @MartinKonecny Resource#toJSON() 实际上返回一个对象,而不是字符串,所以这个答案是正确的解决方案。
    • 如果你从 $resource 取回一个数组,toJSON 将不可用。
    【解决方案2】:

    您需要从后端返回像 {'result': { 'some_key': 'some_val' }} 这样的包装结果。 或者像上面描述的那样做。

    Diary.getSharedWithMe(function(data) {
            delete data.$promise;
            delete data.$resolved;
            _self.sharedDiariesWithMe = data;
        }, function(error) {
            console.log(error)
        });
    

    【讨论】:

      【解决方案3】:

      $resource 返回一个对象或数组,在调用完成时将包含您的数据。所有这些功能都可以帮助您,$resource 主要用于 CRUD 操作。如果你想要数据,你必须等待它被返回,所以你不妨使用 Promise。如果您想剥离所有这些属性,您可以使用angular.toJson 将其转换为 json,但 Angular 在将其发布回资源或 $http 调用时会为您执行此操作,因此您不必这样做。

      $scope.data = $resource("http://foo.com/bar.json").get();
      // $scope.data does not have your data yet, it will be
      // populated with your data when the AJAX call completes
      ...
      // later in a call from a save button maybe you can just do
      // this to post your changes back:
      $scope.data.$save();
      

      【讨论】:

      • angular.toJson 有效,谢谢。但我也想展平数据并获取密钥,而 angular.toJson 似乎不适用于常见的平面功能。
      【解决方案4】:

      因此,如果其他人在这里绊倒并且不理解 promises/angularjs,这就是正在发生的事情。当你使用.then().get() 时,你会得到一个promise 和一些辅助函数都在同一个对象中。这太棒了,因为这样您就不必担心定义的回调以及数据是否可用,因为 promise 对象总是具有一些属性。这个对象包含你在另一个对象内的原始数据。所以 promise 对象是嵌套的,你只需要在数据准备好时引用其中的数据对象。

      这就是我正在做的事情

           $resource("http://foo.com/bar.json").get().
               $promise.then(function(data){ $scope.result = data}, 
      //data is actually a promise object.
                        function(error){ $scope.msg = "error" } );
      

      承诺对象

      请注意,数据实际上位于另一个名为“数据”的对象下。因此,在您的成功回调中仅获取在这种情况下您应该执行的数据:data.data

      【讨论】:

      • 我没有看到data.data,在使用.query() 时,我看到$promise 和$resolved 都混合到同一个对象/数组中......我错过了什么吗?使用 .query() 时,循环遍历多个项目的结果很痛苦
      • 实际上,即使您在最新版本的 Angular 中使用 get().$promise.then()。它仍然会向您发送 $promise 和 $resolve。所以你需要使用data.toJSON()。当然,这是在您的服务器使用 REST 的情况下
      • 我遇到了同样的问题,但有一个替代解决方案。类似问题我已经回复过了,你可以找到here
      【解决方案5】:

      要从每个请求中自动删除它们,您可以添加一个拦截器:

      angular.module('app').config(config);
      
      config.$inject = ['$httpProvider'];
      function config($httpProvider) {
          $httpProvider.interceptors.push(interceptor);
      }
      
      interceptor.$inject = [];
      function interceptor() {
          return {
              request: (config) => {
                  if (config.data) {
                      delete config.data.$promise;
                      delete config.data.$resolved;
                  }
                  return config;
              }
          };
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-09
        • 2016-07-16
        • 1970-01-01
        • 2014-05-11
        相关资源
        最近更新 更多