我一直在玩着梦幻般的Ractive.js库(不要与Facebook的 Reactive .js混淆)。我发现你可以使用以下模板代码渲染二维:
<div class="container">
{{ #frameContainer:i }}
<div class="row">
{{ #frameContainer[i] }}
<div on-click="cell-click" class="cell {{ . ? 'on' : 'off' }}"></div>
{{ /frameContainer[] }}
</div>
{{ /frameContainer }}
</div>
这完全符合我的预期,内部cell-click
事件返回正确的密钥路径(例如frameContainer.2.4
)。
然后我想把它变成一个三维数组(添加一个“时间”轴)。但是,以下方法无效:
<div class="container">
{{ #frameContainer[time]:i }}
<div class="row">
{{ #frameContainer[time][i] }}
<div on-click="cell-click" class="cell {{ . ? 'on' : 'off' }}"></div>
{{ /frameContainer[][] }}
</div>
{{ /frameContainer }}
</div>
time
表示当前时间值(它一次只会显示一个“时间” - 当你这样说时,这似乎很明显......)。
这...有点工作。它会按原样显示网格,但cell-click
事件的返回键路径不再正确,返回${frameContainer-time-8-}.2
之类的内容 - 已丢失time
值(并且已经过了一些奇怪的)。
显然,我可以通过使用currentFrame
值来实现它,我可以使用ractive.set()
来渲染它,但这似乎不那么优雅。有没有办法纯粹在模板中做到这一点?而且,如果没有,那么最有效的方法是什么呢?
谢谢!
答案 0 :(得分:2)
这非常棘手。基本上,${frameContainer-time-8-}
密钥路径是Ractive唯一标识expression的方式,${frameContainer-time-8-}.2
表示'表达式评估为的第三个成员'。
这里发生的事情是:当Ractive的解析器看到{{ #frameContainer[time][i] }}
部分时,它将frameContainer[time][i]
解析为JavaScript表达式并将其转换为以下内容(您可以自己尝试 - Ractive.parse('{{#frameContainer[time][i]}}')
):
{
r: ['i','time','frameContainer'],
s: '${2}[${1}][${0}]'
}
呈现模板时,Ractive会为该表达式创建评估程序,该表达式具有从字符串(s
属性)生成的函数,并监视{{1} }和time
值(不需要观看frameContainer
,因为它无法更改)。当这些值中的任何一个或两个都发生变化时,该函数将作为参数执行。如果它返回更改的值,则Ractive需要更新视图。
由于有一种很好的机制可以将视图模型更改传播到视图 - 键路径 - 这就是评估者使用的方法。为了做到这一点,它需要创建一个唯一的密钥路径,因此i
(它不能包含点或方括号,因为Ractive会尝试拆分它们。)
所以这就是事情:表达式密钥路径是单向的。你不能像常规密钥路径一样${frameContainer-time-8-}
,因为Ractive无法弄清楚对应的底层属性(或者是否有一个 - 它可能是所有知道的衍生值)。
最简单的解决方法可能是做这样的事情:
ractive.set('${frameContainer-time-8-}.2', 'true')
然后,您可以在<div on-click="cell-click:{{time}},{{i}}" class="cell {{ . ? 'on' : 'off' }}"></div>
处理程序中使用time
和i
值(它们将是cell-click
之后的第二个和第三个参数。)
我在这里做了一个简化的演示(假设我理解正确):http://jsfiddle.net/rich_harris/LYEGX/
另一种方法是完全取消密钥路径并使用适配器。我不会在这里详细介绍所有细节,因为它可能不是您正在寻找的答案,但有一些documentation和example(部分链接目前已过期,抱歉...)。简而言之,此方法假设您可以在应用中使用非POJO。