使用$ resource在AngularJS中创建数据服务的正确方法是什么?

时间:2015-03-27 09:15:39

标签: angularjs rest service angular-resource angular-services

我正在使用Angular的$ resource服务来调用RESTful Web服务。目前我正在这样做:

app.factory('data', function($resource) {
    // Creating resource objects for all resources I have.
    var usersResource = $resource('http://example.com/api/users/:id', {id: '@id'});
    var universitiesResource = $resource('http://example.com/api/universities/:id', {id: '@id'});
    // ..
    // Initializing more resource objects.

    return {
        users: {
            getAll: function() {
                return usersResource.query();
            }
            // ..
            // More methods..
        },
        universities: {
            getAll: function() {
                return universitiesResource.query();
            }
            // ..
            // More methods..
        }
        // ..
        // More objects.
    }
});

另一种方法是为每个资源建立不同的数据工厂。所以,我的问题是这样做的正确的方式是什么?为什么?它看起来更加结构化,只有一个数据工厂,但是所有这些资源对象都会造成很大负担并降低应用程序的性能吗?

1 个答案:

答案 0 :(得分:2)

如果您的应用程序不是那么大,并且您不会在一个地方收集数十个资源,那么您的方式看起来不错。如果是这样,这个“全球数据工厂”将会太大,团队中的每个人都会不断编辑它。 还有一个考虑因素 - 您的资源通常比普通的CRUD操作更复杂。您必须使用官方文档中描述的其他功能扩展它们:

var CreditCard = $resource('/user/:userId/card/:cardId', {userId:123, cardId:'@id'}, {
  charge: {
         method:'POST', 
         params:{charge:true}
   }
 });

想象一下,如果你将这样的声明放在一个地方,它会是怎样的。

我采用了不同的方法 - 根据需要提供资源,甚至在默认CRUD操作的情况下也不会声明它们。 我们有以下工厂:

angular.module("app").factory("resourcesByConvention", ResourcesByConvention);

ResourcesByConvention.$inject = ['$injector', '$resource'];
function ResourcesByConvention($injector, $resource) {
    return {
        getResource: function (resourceName) {
            var resource;
            try{
                resource=$injector.get(resourceName);
            }
            catch(error)
            {
                resource = $resource('/api/' + resourceName, {}, {
                    update: {
                        method: 'PUT'
                    }
                });

            }
            return resource;
        }
    }
}

我们在每个地方注入这个工厂并做:

var usersResource=resourcesByConvention.getResource("users");

如果您的资源只需要简单的CRUD操作 - 这个工厂只会为您创建它。但是如果你需要更复杂的东西,你只需创建并注册自己的东西。例如,您将注册以下内容:

app.factory('AccountResource', ['$resource', function($resource) {
return $resource('/account/:id', null,
    {
        update: { method:'PUT' },
        getBalance: {method: 'GET'},
        charge: {method: 'POST'}
    });
}]);

稍后请求:

var accountResource=resourcesByConvention.getResource("AccountResource");

结论:您有单一服务来获取所需的任何资源,您可能根本不会声明典型的CRUD资源。