原创翻译自Kirk Bushell的BLOG:
我发现一个Angular JS中的关键问题是(以我喜欢的代码工作方式来说)$save方法在ngResource中将只会使用POST沿着有效载荷提交到服务器。新建和更新记录操作都是这样的,对来自服务器的新和旧的对象都是如此。这破坏了 RESTful约定的更新操作应该使用PUT或者PATCH操作。我下面建议的解决方案拓展了现有的ngResource实现,提供了更多的默认选项,同时精简了我们的工作流程。完美的用法(恕我直言)应该像下面这样:
var user = new User;user.name = 'Kirk Bushell';user.$save(); // POSTvar user = User.get( { id: 1 });user.name = 'John smith';user.$save(); // PUT
如果我们深入ngResource的代码中,这样的需求是可能的,关于怎么样去简化它的实现(这应该是由 Angular 的团队来完成)。不幸的是,它的确意味着如果我们想要同时用POST/PUT来实现保存操作,我们不得不用两个不同的方法(这不是我的风格)。恕我直言,保存就是保存 --- 让你的模块/类 来定义这是什么样的保存(新建或是更新)操作。我们需要做的是用我们自己的默认实现来拓展ngResource提供的 $resource工厂。让我们接着看下去。
var module = angular.module( 'my.resource', [ 'ngResource' ] );module.factory( 'Resource', [ '$resource', function( $resource ) { return function( url, params, methods ) { var defaults = { update: { method: 'put', isArray: false }, create: { method: 'post' } }; methods = angular.extend( defaults, methods ); var resource = $resource( url, params, methods ); resource.prototype.$save = function() { if ( !this.id ) { return this.$create(); } else { return this.$update(); } }; return resource; };}]);
这里我们定义了一个自定义模块 - my.resource,这个模块可以被注入到其他你想要这个拓展功能的模块中。我们接着以一个依赖为我们的Resource工厂注入$resource,并做一些小魔法,让我们研究下吧。
首先,我们定义了一个新的默认数组。它包括了为resource的更新update和新建create方法 - create方法将会被定义成一个POST请求,update方法将会被定义成一个PUT请求。我们为什么会想要这两个额外的方法?因为它允许我们做更明确的请求,正因如此,我们需要重载$save方法!
我们拓展了任何我们会提供给resource的方法。然后,我们定义我们的新resource和通过重载$save方法拓展它。这个方法会检查id字段是否包含在一个资源对象中,如果有id字段,它将会调用我们定义在default中的$update方法;如果没有id字段,它会调用$create方法,很简单吧!
但是 - 我们怎么在我们自己的资源中使用它呢?小菜一碟。
var module = angular.module( 'services', [ 'my.resource' ] );module.factory( 'User', [ 'Resource', function( $resource ) { return $resource( 'users/:id', { id: '@id' } );}]);
现在你可以看到 - 我们对待它就像对待其他的资源一样注入,唯一的区别是 - 我们定义了我们的 $resource依赖于我们自己进行拓展ngResource 后的Resource。
这的确相当简单不是么。现在你可以让你的资源对象调用变的正常了!一如往常,欢迎大家的回复,批评,和建议。