【问题标题】:Default $resource POST data默认 $resource POST 数据
【发布时间】:2012-06-29 16:37:37
【问题描述】:

这可能很奇怪,但我需要使用模块的工厂方法为我的 $resource 指定一些默认的 POST 数据。

有没有人知道如何在 AngularJS 中做到这一点?

编辑:

好吧,我想做这样的事情:

/**
 * 模块声明。
 * @type {对象}
 */
var services = angular.module("services", ["ngResource"]);

/**
 * 产品处理服务
 */
services.factory("产品", function($resource) {
    返回 $resource("http://someUrl", {}, {
        获取:{方法:“GET”,参数:{productId:“-1”}},
        更新:{方法:“POST”,参数:{},数据:{someDataKey:someDataValue}}
    });
});

data 是我未来 POST 请求的默认数据。

【问题讨论】:

  • 你在这些数据中发送了什么?如果你发送一个令牌,你应该在 headers 中发送它,不一定在 postData...

标签: javascript angularjs


【解决方案1】:

这并不是真正的角度方式来做这样的事情,因为如果你这样做会失去数据一致性并且它不会反映在你的模型中。

为什么?

资源工厂创建对象并将对象实例数据用作 POST。我查看了文档和 angular-resource.js,似乎没有办法在不修改 angular-resource.js 的情况下为资源创建的对象指定任何默认自定义属性。

你可以做的是:

services.factory("Product", function($resource) {
    return $resource("http://someUrl", {}, {
        get   : {method: "GET", params: {productId: "-1"}},
        update: {method : "POST"}
    });
});

在你的控制器中:

$scope.product = {}; // your product data initialization stuff
$scope.product.someDataKey = 'someDataValue'; // add your default data

var product = new Product($scope.product);
product.$update();

【讨论】:

  • 我想我们必须坚持这一点,不能设置默认的 POST 值:)
【解决方案2】:

我认为这取决于您如何调用更新函数。如果您阅读 Angular 主页的教程,在“连接后端”下,mongolab.js 提供了一个“项目”工厂。逐字复制:

angular.module('mongolab', ['ngResource']).
factory('Project', function($resource) {
  var Project = $resource('https://api.mongolab.com/api/1/databases' +
      '/angularjs/collections/projects/:id',
      { apiKey: '4f847ad3e4b08a2eed5f3b54' }, {
        update: { method: 'PUT' }
      }
  );

  Project.prototype.update = function(cb) {
    return Project.update({id: this._id.$oid},
        angular.extend({}, this, {_id:undefined}), cb);
  };

  Project.prototype.destroy = function(cb) {
    return Project.remove({id: this._id.$oid}, cb);
  };

  return Project;
});

用法是先获取Project的一个实例:

project = Project.get({id:1});

然后进行一些更改后进行更新:

project.update(someFunction);

在您的情况下,您可以更改更新以始终添加您需要的数据:

Product.prototype.update = function(cb) {
  return Product.update({},
      angular.extend({}, this, {someDataKey: someDataValue}), cb);
};

否则,您很可能会将键/值对放在参数中:

    update: {method : "POST", params:{someDataKey: someDataValue}}

它将与 URL 中的键/值对一起发布,但现在大多数应用服务器无论如何都会将该对扔到 params 对象中。

【讨论】:

    【解决方案3】:

    我认为大多数人都错过了文档 here 中的一个小宝石。

    non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
    

    这表明您可以执行以下操作。

    var User = $resource('/user');
    postData = { name : 'Sunil', 'surname' : 'Shantha' };
    
    var user = User.save({notify:'true'}, postData, function() {
      // success!
    });
    

    进行保存动作(post)时的第二个参数是post数据。

    【讨论】:

      【解决方案4】:

      包装函数将起作用。

      function myPost(data) {
        return $http.post('http://google.com', angular.extend({default: 'value'}, data))
      }
      
      myPost().success(function(response) { ... });
      

      【讨论】:

      • 它确实会起作用,但不是我在你回答后指出的方式:)
      【解决方案5】:

      这能解决你的问题吗?

      services.factory("Product", function($resource) {
        return $resource("http://someUrl", {}, {
          get   : {method: "GET", params: {productId: "-1"}},
          update: {method : "POST", params:{}, data: {someDataKey: someDataValue}}
        });
      });
      services.factory("DefaultProduct", function(Product) {
        return function(){
           return new Product({
              data:"default";
           });
        };
      });
      services.controller("ProductCTRL",function($scope,DefaultProduct){
        $scope.product = new DefaultProduct();
      });
      

      【讨论】:

        【解决方案6】:

        您可以使用默认设置 merge 您的参数。 params 中的所有都将由默认对象提供。所有可用的东西都将被myParams覆盖

        services.factory("Product", function($resource) {
            return $resource("http://someUrl", {}, {
                get   : {method: "GET", params: {productId: "-1"}},
                update: {method : "POST", params:angular.extend(myDefault, myParams);}
            });
        });
        

        myParams 是您的变量列表,myDefault 是您作为 json 对象的默认值。

        【讨论】:

          【解决方案7】:

          您可以使用 transformRequest 选项为您的 $resource 使用 POST 方法的操作设置请求的默认字段。

          比如这样的

          function prependTransform(defaults, transform) {
          
           // We can't guarantee that the default transformation is an array
           defaults = angular.isArray(defaults) ? defaults : [defaults];
          
           // Append the new transformation to the defaults
           return [transform].concat(defaults);
          }
          
          ctrl.factory('MyResource', ['$resource', '$http',
          function($resource, $http) {
              return $resource('/path/to/myresource/:id', {id : '@id'},
                     { 
                         create : {
                             method : 'POST',
                             transformRequest : prependTransform($http.defaults.transformRequest,
                                function(data, headers) {
                                     return addDefaultField(data);
                                }
                            ),
                         },
                     });
              }
          ]);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-25
            • 2014-10-14
            • 1970-01-01
            • 2015-04-21
            • 2023-03-03
            相关资源
            最近更新 更多