Ractive.js中的多维数组

时间:2014-01-28 16:39:04

标签: javascript view multidimensional-array ractivejs

我一直在玩着梦幻般的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()来渲染它,但这似乎不那么优雅。有没有办法纯粹在模板中做到这一点?而且,如果没有,那么最有效的方法是什么呢?

谢谢!

1 个答案:

答案 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无法弄清楚对应的底层属性(或者是否有一个 - 它可能是所有知道的衍生值)。

解决方案1 ​​

最简单的解决方法可能是做这样的事情:

ractive.set('${frameContainer-time-8-}.2', 'true')

然后,您可以在<div on-click="cell-click:{{time}},{{i}}" class="cell {{ . ? 'on' : 'off' }}"></div> 处理程序中使用timei值(它们将是cell-click之后的第二个和第三个参数。)

我在这里做了一个简化的演示(假设我理解正确):http://jsfiddle.net/rich_harris/LYEGX/

解决方案2

另一种方法是完全取消密钥路径并使用适配器。我不会在这里详细介绍所有细节,因为它可能不是您正在寻找的答案,但有一些documentationexample(部分链接目前已过期,抱歉...)。简而言之,此方法假设您可以在应用中使用非POJO。