【问题标题】:Getting ids for newly created resource in Angular factory from server从服务器获取 Angular 工厂中新创建资源的 ID
【发布时间】:2013-06-22 19:53:02
【问题描述】:

我正在构建一个由 Node.js/Mongodb 应用程序支持的 Angular 应用程序。

每个资源的id是由MongoDB在创建资源时生成的。

在我将POST 我的新对象从工厂发送到服务器后,服务器返回一个201 响应代码,其中位置标头设置为新资源的URI。如何处理响应,然后使用正确的id 更新记录?

angular.module('myApp.Todoservices',['ngResource']).
factory('Todo',function($resource){
    return $resource('http://localhost\\:3000/todos/:id', {id:'@_id'}, {
        getAll: {method:'GET', isArray:true},
        update : {method:'PUT'},
        create : {method:'POST'},
        delete : {method:'DELETE'}
    });
});

【问题讨论】:

  • 服务器不也是返回新创建的记录吗(在其中可以找到新创建记录的ID)?
  • @callmekatootie 据我了解,正确的响应是 201 Created,带有指向新资源的 Location 标头。见w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30。我将编辑我的问题以澄清。

标签: javascript mongodb rest angularjs


【解决方案1】:

如前所述,$resource 不支持此功能,我不知道为什么。但是,这是我的解决方法。

var tmpPart = new MyResource({name: $scope.item.name});
tmpPart.$create(function(_tmpPart, responseHeaders){
    $resource(responseHeaders("Location")).get(function(tempResourceObject){
        $scope.myResourceObjects.push(new MyResource(tempResourceObject))
    });
});

new MyResource(tempResourceObject) 是资源对象的新实例,你可以用它做任何你想做的事情。

【讨论】:

    【解决方案2】:

    您可以使用自定义服务覆盖默认的 $resource 服务。 抱歉,coffeescript 和 ng-classify

    class Resource extends Factory
      constructor: ($resource, $http) ->
        return class ResourceFactory extends $resource
          constructor: (url, paramDefaults, actions, options)->
            class Res extends super
              $save: (params, success, error)=>
                super(
                  params
                , (response, responseHeaders)=>
                  if location = responseHeaders("Location")
                    $http
                    .get(location)
                    .then (httpResponse)->
                      success new Res httpResponse.data, responseHeaders
                    , error
                  else
                    success response, responseHeaders
                , error
                )
    
            return Res
    

    之后

    Users = Resource '/users'
    user = new Users name:'foo'
    user.$save (savedUser)->
      savedUser # will be created from data loaded from location header of post response
    

    【讨论】:

      【解决方案3】:

      $resource 服务是底层 $http 服务的高级包装器。

      $resource 方法(post()put()get()、...)的成功和错误回调接收包含 headers() 方法的响应对象。

      使用此方法,您可以获取所有响应标头的数组,或者,如果您提供特定标头名称作为参数,则可以获取特定标头值:

      var successCallback = function(response){
        var location = response.headers('location');
        // extract resource ID form the location header here...
      }
      
      $scope.todo.post(data, successCallback);
      

      $http header getter 函数在$http docs中描述

      【讨论】:

        【解决方案4】:

        看起来 $resource(仍然)不支持那个 [1],所以现在使用 $http [2] 服务。

        [1]https://github.com/angular/angular.js/issues/7037

        [2]http://docs.angularjs.org/api/ng/service/$http

        【讨论】:

          【解决方案5】:

          我正在使用“angular-resource”:“1.3.11”,它看起来很简单。根据 Angular 资源文档:

          类对象或实例对象上的动作方法可以是 使用以下参数调用:

          HTTP GET “类”操作:Resource.action([parameters], [success], [错误])

          非 GET “类”操作:Resource.action([parameters], postData, [成功], [错误])

          非 GET 实例操作: instance.$action([参数], [成功], [错误])

          成功回调是 使用 (value, responseHeaders) 参数调用。

          使用 (httpResponse) 参数调用错误回调。

           todo.save(postData,
                 function (value, responseHeaders) {
                     $scope.id = responseHeaders('Location').split('/').pop();
                 }
          );
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-01-20
            • 1970-01-01
            • 2018-12-13
            • 1970-01-01
            • 2023-03-27
            • 2011-02-15
            • 2016-04-20
            • 1970-01-01
            相关资源
            最近更新 更多