And*_*rea 2 javascript ractivejs
我开始使用Ractive,我想更好地了解如何制作可重用的组件.编写可在不同情况下使用的通用小部件非常容易.我的问题是,我的应用程序中的数据通常不是小部件所期望的形状,我不知道如何扩展小部件以使其更具应用程序特定性.
举一个具体的例子,假设我正在编写一个Ractive组件来设计折线图.我会做一些事情
var Chart = Ractive.extend({
template: chart,
data: {
points_to_path: function(points) {
// whatever
}
}
});
Run Code Online (Sandbox Code Playgroud)
用像这样的模板
<svg>
{{# points_to_path(points) }}
<path d="{{ path }}" />
{{/ end of path }}
</svg>
Run Code Online (Sandbox Code Playgroud)
这个组件可以像
var chart = new Chart({
data: {
points: [[1, 2], [3, 4], [5, 6]]
}
});
Run Code Online (Sandbox Code Playgroud)
现在假设我实际上需要使用这样的组件.可能我的数据不是像points上面那样以双组件数组的形式出现的.也许我有更喜欢的东西
[
{
date: 'aug 2011',
value: 12.51
},
{
date: 'sep 2011',
value: 12.38
},
...
]
Run Code Online (Sandbox Code Playgroud)
所以,我想要做的是更具体的应用程序Chart,接受上述形式的数据.我没有看到一个简单的方法Chart.extend,因为对points变量的引用是硬编码的chart.html.
在像Backbone这样的框架中,视图是嵌套的,因此我可以将内部窗口小部件包装到更大的视图中,并在外部视图中定义数据转换的逻辑.我不太确定如何从Ractive继续这里.也许我应该从一开始就以不同的方式设计小部件.
更一般地说,我的问题是我可以在Ractive中编写小组件,但我不太确定如何将它们组合成更大的组件.
Ractive专业化或扩展组件的惯用方法是什么?或者将许多组件组合成更大的应用程序?
有几种可能的解决方案.我不确定什么是合格的 - 一般来说,Ractive的理念是'如果它有效,那就是正确的解决方案!' - 我是作者,但是我会留给社区来决定什么是惯用的.
如果您使用d3创建散点图,通常会执行以下操作:
d3.select( 'circle' ).data( points )
.enter().append( 'circle' )
.attr( 'cx', function ( d ) { return d.x; })
.attr( 'cy', function ( d ) { return d.y; })
.attr( 'r', 5 );
Run Code Online (Sandbox Code Playgroud)
换句话说,对于每一个 基准 在数组中的项目,我们提供了一个函数,它提取绘制x和y位置所需的值.
Ractive等效项是在初始化组件时指定一个函数:
<!-- the template -->
<svg>
<path d='{{ points_to_path(points) }}'/>
</svg>
Run Code Online (Sandbox Code Playgroud)
// let's create a chart component that assumes we get an array
// of points with an `x` and a `y` property
var Chart = Ractive.extend({
template: chart,
data: {
points_to_path: function(points) {
// is there a 'normalise' function? If so, normalise
// the data we've been given
if ( var normalise = this.get( 'normalise' ) ) {
points = points.map( normalise );
}
// turn a normalised `{x: x, y: y}` point into 'x,y'
var pointToString = function ( point ) {
return point.x + ',' + point.y;
};
// create the SVG path
return 'M' + points.map( pointToString ).join( ' ' );
}
}
});
// now, we need to create a function that tells the Chart
// component how to deal with the data we're about to give it
var chart = new Chart({
data: {
points: [[1, 2], [3, 4], [5, 6]],
normalise: function ( point ) {
return { x: point[0], y: point[1] };
}
}
});
Run Code Online (Sandbox Code Playgroud)
因此,如果你有一个带有date和value属性的点数组,你只需要传递一个返回的normalise函数(或者normalize如果你更喜欢美国拼写......){x: point.date, y: point.value}.
(当然,points_to_path如果更容易,你可以覆盖整个函数.)
另一种方法是在不同情况下使用不同的部分:
<!-- widget template -->
<h2>This is a widget</h2>
<div class='contains-dynamic-contents'>
{{>inner}}
</div>
Run Code Online (Sandbox Code Playgroud)
var widget = new Widget({
el: 'widgetContainer',
partials: {
inner: '<p>This paragraph will appear inside the div</p>'
}
});
Run Code Online (Sandbox Code Playgroud)
这为您提供了很多自由,但折线图示例可能更难以适应.
第一种方法也适用于内联组件 - 这个例子假设您正在使用开发(0.3.8-pre)版本,该版本即将发布:
Ractive.components.linechart = Chart;
Run Code Online (Sandbox Code Playgroud)
<div class='application'>
<h1>This is a chart</h1>
<linechart points='{{someData}}' normalise='{{someNormaliseFunction}}'/>
</div>
Run Code Online (Sandbox Code Playgroud)
(Protip:您可以指定默认normalise函数Chart.data.normalise = someFunction.)
第二种方法有点棘手 - 您必须动态切换部分初始化:
Chart = Ractive.extend({
beforeInit: function () {
this.partials.inner = ( someCondition ? thisPartial : thatPartial );
},
// ...
});
Run Code Online (Sandbox Code Playgroud)
对不起这个回复的史诗长度,希望你想要的答案就在这里!
| 归档时间: |
|
| 查看次数: |
1778 次 |
| 最近记录: |