2

我一直在玩奇妙的 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>

wheretime代表当前时间值(它一次只会显示一个“时间” - 当你这样说时似乎很明显......)。

这......有点作品。它按应有的方式显示网格,但返回的cell-click事件键路径不再正确,返回类似于${frameContainer-time-8-}.2- 的东西,它已经失去了time值(并且有点奇怪)。

显然,我可以通过使用currentFrame渲染并切换的值来做到这一点ractive.set(),但这似乎不太优雅。有没有办法纯粹在模板中做到这一点?而且,如果不是,那么最有效的方法是什么?

谢谢!

4

1 回答 1

2

这是一个相当棘手的问题。基本上,${frameContainer-time-8-}keypath 是 Ractive 唯一标识一个表达式的方式, ${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属性)生成的函数,它监视timeframeContainer值(它不需要监视i,因为它不能改变)。当其中一个或两个值发生变化时,函数会以它们作为参数执行。如果它返回一个改变的值,Ractive 需要更新视图。

由于有一个很好的机制可以将视图模型更改传播到视图 - 键路径 - 这就是评估器使用的。为此,它需要创建一个唯一的 keypath,因此${frameContainer-time-8-}(它不能包含点或方括号,因为 Ractive 会尝试在这些上拆分)。

所以事情是这样的:表达式键路径是单向的。您不能ractive.set('${frameContainer-time-8-}.2', 'true')像使用常规键路径那样做,因为 Ractive 无法确定对应的底层属性(或者即使有一个 - 它可能是它所知道的所有衍生值)。

解决方案 1

最简单的解决方法可能是执行以下操作:

<div on-click="cell-click:{{time}},{{i}}" class="cell {{ . ? 'on' : 'off' }}"></div>

然后,您可以在处理程序中使用timeandicell-click(它们将是第二个和第三个参数,在 之后event)。

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

解决方案 2

另一种方法是完全取消键路径并使用适配器。我不会在这里详细介绍所有细节,因为它可能不是您正在寻找的答案,但有一些文档示例(一些链接目前已过时,抱歉......)。简而言之,此方法假定您能够在应用程序中使用非 POJO。

于 2014-01-30T04:53:21.797 回答