在AngularJS中创建CRUD服务的最佳实践



在AngularJS应用程序中设计CRUD服务/工厂的最佳实践是什么,该应用程序处理单个多个实体?

例如,我在一个名为customerFactory的工厂中有一个customer对象,它包含类似于以下的结构:

var customer = {
    newCustomer: false,
    selfUri: null,
    editUri: null,
    deleteUri: null,
    customerName: null,
    customerAddress: null
};

我在那个调用REST服务的工厂上还公开了以下示例函数:

var create = function() {
    $http.post('api/customers/1', { customer: customer } );
}
var read = function() {
    $http.get('api/customers', { params { uri : customer.selfUri } );
}
var update  = function() {
    $http.put('api/customers/1', { customer: customer } );
}
var delete = function() {
    $http.delete('api/customers/1', { uri: customer.deleteUri } );
}
// This is an oddity and probably shouldn't be in this factory??
var readAll = function() {
    $http.get('api/customers', {} );
}

所有这些方法基本上都适用于工厂内的customer对象。

readAll()方法是否应该放入另一个处理检索所有客户的服务/工厂,而不是放入上面的工厂,因为它处理单个实体?检索多个实体的REST调用是否应该放在自己的工厂中?

示例:customerFactory

// Deal with single customer entities
app.factory('customerFactory', ['$http',
    function($http) {
        var customerFactory = {};
        var customer = {
            newCustomer: false,
            selfUri: null,
            editUri: null,
            deleteUri: null,
            customerName: null,
            customerAddress: null
        };
        var create = function() {
            $http.post('api/customers/1', { customer: customer } );
        }
        var read = function() {
            $http.get('api/customers', { params { uri : customer.selfUri } );
        }
        var update  = function() {
            $http.put('api/customers/1', { customer: customer } );
        }
        var delete = function() {
            $http.delete('api/customers/1', { uri: customer.deleteUri } );
        }
        customerFactory.create = create;
        customerFactory.read= read;
        customerFactory.update= update;
        customerFactory.create = delete;
       return customerFactory;
    }]);

示例:customersFactory

// Deal with multiple customer entities
app.factory('customersFactory', ['$http',
    function($http) {
        var customersFactory = {};
        var customers = {};
        var readAll = function() {
        $http.get('api/customers', {} ).then(function(response) {
            customers.push(response.data);
        });
        customersFactory.readAll = readAll;
        return customersFactory;
    }]);

让我在前言中说我对angular很陌生。话虽如此,您可以创建一个在CustomerList和Customer服务中使用的CustomerClass。customerlist服务将返回一个数组,而客户服务将返回单个客户。即使我用.factory()将它们添加到应用程序中,它们也被用作服务。

请注意,CustomerClass只返回没有新关键字的函数(类)。这样,您就可以在其他服务中自己实例化一个新的CustomerClass。self.init函数是构造函数,它将自动扩展您传入的对象的值。self.init在声明下自动调用。

我在工厂中使用Self.ready,所以如果我使用ng repeat,它不会显示,除非工厂的状态为ready=true。因为您是以一种ajaxy的方式提取数据,所以在收到数据并准备好之前,您不想用任何东西更新视图。

myApp.factory("CustomerClass", function ($http) {
    function CustomerClass(extendableObject) {
        var self = this;
        self.init = function () {
            //will extend newCustomer, selfUri, editUri etc... fields
            angular.extend(self, extendableObject);
        };
        self.init();
    }
    return CustomerClass;
});
myApp.factory("CustomerListService", function ($http, CustomerClass) {
    function CustomerList() {
        var self = this;
        self.ready = false;
        //return array of customer objects
        self.readAll = function () {
            var customers = [];
            $http.get('api/customers/list')
                .success(function (payload) {
                    angular.forEach(payload.customers, function (customer) {
                        customers.push(new CustomerClass(customer));
                    });
                    self.ready = true;
                    return customers;
                });
        };
    }
    return new CustomerList;
});
myApp.factory("CustomerService", function ($http, CustomerClass) {
    function Customer() {
        var self = this;
        self.ready = false;
        //return one customer object
        self.read = function (id) {
            $http.get('api/customers/single', {params: {id: id}})
                .success(function (payload) {
                    return new CustomerClass(payload);
                    self.ready = true;
                });
        };
    }
    return new Customer;
});

我希望您使用更适合您的$resource

只需要在服务中编写一个方法,就可以删除服务中的所有冗余代码,就像它将充当GET, PUT, DELETE & UPDATE 一样

工厂代码

var app = angular.module('mainApp',['ngResource']);
app.factory('Customer', function($resource) {
  return $resource('/api/customers/:id'); // Note the full endpoint address
});

控制器

app.controller('CustomerController', function($scope, Customer) {
    var customer = Customer.get({ id: $scope.id }, function() {
        console.log(customer);
    }); // get() returns a single entry
    var customers = Customer.query(function() {
        console.log(customers);
    }); //query() returns all the customers
    $scope.customer = new Customer(); //You can instantiate resource class
    $scope.customer.data = 'some data';
    Customer.save($scope.customer, function() {
        //data saved. do something here.
    }); //saves an customer. Assuming $scope.customer is the Entry object  
});

通过使用单一服务方法,您可以做很多事情。在处理REST API时,我更喜欢使用$resource

有关更多详细信息,请访问此处

更新

如果你仍然想使用$http。为了使你的代码更可重用,我将避免创建customerFactory,因为它具有与客户相关的所有方法。我不想创建angular.constant,通过使用该常量数组,我们将使用该数组创建一个新的服务。

常量

app.constant('customerMethods', [
            {name: 'create', type: 'post', url: 'api/customers/1', dataParam:{ customer: customer }},
            {name: 'read', type: 'get', url: 'api/customers', dataParam:{ params: { uri : customer.selfUri }},
            {name: 'create', type: 'post', url: 'api/customers/1, dataParam:{ customer: customer }}, //you need to provide customer object
            {name: 'create', type: 'post', 'api/customers/1', dataParam: { customer: customer }},//you need to provide customer object
]);

工厂

app.factory('customersFactory', ['$http', 'customerMethods', 'customer',
    function($http, customerMethods, customer) {
        var customersFactory = {};
        var customers = {};
        var customerMethods = customerMethods;
        angular.forEach(customerMethods, function(val, index) {
            angular.extend(customersFactory, {
                val.name: function() {
                    return $http[val.type](val.url, val.dataParam);
                }
            });
        });
        return customersFactory;
    }
]);

您重新分解的代码将如上图所示。虽然它没有经过测试,但我相信它只会是这样的。

希望这能对你有所帮助。谢谢

最新更新