在 AngularJS 中构建流畅的服务

Build fluent service in AngularJS

我在AngularJS有一个简单的工厂:

(function(){
'use strict';

    angular
        .module('myModule', [])
        .factory('myService', service);

    function service(){
        var products= function(p1, p2, p3, ..., pn) {
            var url = "http://something.url/api/action";
            var data = {
                'p1': p1,
                'p2': p2,
                ...
                'pn': pn,
            }

            // return data           
            return $http
                .post(url, data)
                .then(function (response) {
                    return response.data;
                });
        }

        return {
            Products : products
        };
    }
})();

我在这样的控制器中使用此服务:

myInjectedService
    .Products(vm.p1, vm.p1, ... , vm.pn)
    .then(successCallbackFn)
    .catch(failureCallbackFn);

每个参数(p1, ..., pn)用于过滤最终结果。这就像一个魅力!但有一个小缺点:Products 有许多可接受的参数,很难知道我是否发送了正确的参数,这听起来有点容易出错。我想要的是流利的 API 服务,使所有内容更易于阅读,这很棒:

myInjectedService
    .Products()
    .FilterById(p1)
    .WhereCategoryIs(p2)
    ...
    .WhereSomethingElseIs(pn)
    .Send()
    .then(successCallbackFn)
    .catch(failureCallbackFn);

以前 HTTP 调用的任务由 Products 调用处理。现在Products(),只做一个空查询(即{})。每个后续 FilterByX 将丰富查询(即 {'productId': 'xxx-yyy-1111'})。调用 Send() 将进行真正的 HTTP POST 调用。此调用将使用 data 通过应用的各种过滤器构建。我怎样才能做到这一点?我正在玩原型但没有成功。

您可以通过定义一个新的 class 并像这样使用原型来实现您想要的。

在流畅的方法中,记得return对象本身。

   function service(){
        var products = function(url) {
          
            // Define a new Product class
            var Products = function() {
              this.url = url;
              this.data = {};
            };
            
            // Add the function
            Products.prototype.FilterById = function(id) {
                this.data.id = id;
                // To make it fluent, return the object itself
                return this;
            };
              
            Products.prototype.FilterByCategory = function(category) {
                this.data.category = category;
                return this;
            };
              
            Products.prototype.send = function() {
               console.log(this.data);
            };
              
            // Return an instance of the Products class
            return new Products();
          };
      
        return {
            Products : products
        };
   };
   
 service().Products().FilterById(1).FilterByCategory("Item").send();

您可以在此处阅读更多相关信息:https://www.sitepoint.com/javascript-like-boss-understanding-fluent-apis/