在 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/
我在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/