正在寻找一种重构D3.js风格的方法链接模式的方法
Looking for a way to refactor D3.js-style method chaining pattern
在学习D3.js时,我看到了一篇博客文章,解释了它的可重用代码单元背后的主要设计模式。我已经复制了下面的相关代码。下面显示模式的方式与D3代码库和插件(示例)中使用模式的方式完全相同。
我对这段代码的一个问题是,它有太多的属性复制粘贴。JavaScript是一种函数式语言,我想我可以重新考虑样板代码,但我想不出一种方法。arguments
和value
参数很容易传递给一个公共函数,但我找不到一种方法来保留对width
和height
属性的引用。
function chart() {
var width = 720, // default width
height = 80; // default height
function my() {
// generate chart here, using `width` and `height`
}
my.width = function(value) {
if (!arguments.length) return width;
width = value;
return my;
};
my.height = function(value) {
if (!arguments.length) return height;
height = value;
return my;
};
return my;
}
事实上,在实际的D3代码库中就是这样做的,这让我怀疑是否有可能重新分解,但我希望这只是一个问题,而不是一个高优先级的问题(新的贡献者正在这样做,因为以前就是这样做)。
我想要的基本上是用替换每个访问者的主体
my.height = function(value) {
return getSet(arguments, value, whatever);
};
调用仍然有一些样板,但至少逻辑是集中的,如果需要,可以只在一个地方更新。
如果在chart
的作用域中定义getSet
,它也可以访问封闭变量。问题是,不能通过名称字符串访问这些变量(除非使用某种eval
)。
您可以通过将所有私有变量封装在未经测试的对象中来避免这种情况:
function chart() {
var props = {
width: 720, // default width
height: 80 // default height
}
function my() {
// generate chart here, using `width` and `height`
}
my.height = function(value) {
// Call getSet with current my instance as this,
// 'height' as the first argument, then value
return getSet.apply(this, arguments.slice().unshift('height'));
};
// Works just like your current accessors, on the props object
function getSet(property, value) {
if (arguments.length > 1) return props[property];
props[property] = value;
return this;
}
return my;
}
问题是,这并不比为每个属性编写几个类似的访问器短多少。您当前的访问器使私有变量实际上是公共的,那么为什么不抛弃它们,转而使用公共变量呢?
已经提供的另一种解决方案是定义一个返回函数的"属性"函数,例如
function property (v) {
return function (_) {
if(!arguments.length)
return v;
v = _;
return this;
};
}
所以你可以说:
function chart() {
chart.width = property.call(chart, 500);
chart.height = property.call(chart, 500);
chart.render = function() {
//render logic goes here
};
return chart;
}
我不能完全相信这一点——我认为消息来源实际上是Mike Bostock(但我找不到原始帖子的链接)
我在我的许多模块中都使用了这个"属性"函数,它省去了很多烦人的打字。您可以很容易地对其进行扩充,以便在传入值发生更改时发出事件。
相关文章:
- 有没有一种方法可以防止img get请求使用css或js发生
- 有条件更新d3.js力图中节点的最佳方法
- 在D3.js中,有没有任何方法可以将x和y方向上的滚动事件绑定到平移svg
- 有没有任何方法可以使用node-js从不同的机器打开浏览器
- 有没有比在app.js上绑定模块名称更好的方法来动态加载视图模型和视图以显示模态
- 有没有一种方法可以获得three.js的最小/lite版本
- Underscore.js某些对象的所有方法的总和
- node.js是否具有'match()'方法如果是,语法是什么
- 当数据库中的某些内容发生变化时调用HTTP方法Meteor.js
- 当用户点击动态创建的链接时,如何调用JS方法.JQuery,ASP.NET MVC
- 从React调用方法.JS州
- 从方法js中的函数获取对象属性
- 是否可以在 Vue 中嵌套方法.js以便对相关方法进行分组
- 主干 - 从我的原型视图调用方法.js
- $(这个).方法(js 或 jquery)
- 如何在噩梦中运行多种评估方法.js
- 如何从骨干中的集合调用模型的方法.js
- 如何在传单中使用 .off() 事件方法.js
- 检查这个的好方法和干净的方法?(JS+HTML)
- 使用爆米花迭代提示方法.js