如何强制Meteor的Blaze应用于#each block

时间:2016-06-06 08:20:25

标签: meteor each meteor-blaze spacebars

我有一个模板,大部分相当于:

<div class="line">
{{#each part in line}}
  <span class="part">{part}</span>
{{/each}}
</div>

其中line: string[]是一行到一个或多个部分的分区。问题是当line的内容发生变化时,模板会尝试将旧元素与新元素匹配(这很好),并将更改逐个(这不是很好)应用于DOM。特别是如果line的旧值为["Hello","world"]且新值为["Hello world"],则会在短时间内向用户显示line[0]的新值结合line[1]的旧值,即["Hello world","world"]。大部分时间都没有被注意到,但是如果部件与屏幕宽度相比足够长,可能会发生<span class="part">Hello world</span><span class="part">world</span>不适合单行,这反过来导致整个进一步的内容移动了一行,只有在最后移除line[1]时才会再移动一行。

我目前使用的一个解决方案是用自定义帮助器#each替换整个{{{ helpMeRenderThisLine line }}}循环,它自动构建HTML字符串,但这显然违反了关注点和我的代码样式。

我是Meteor的新手,但这些是我想调查的方向:

  • 有没有办法以非反应方式呈现循环?我听说有 类似于#constant阻止的东西,但它不再受支持。
  • 有没有办法将整个更新过程“批处理”到一个DOM中 回流?
  • 有没有办法使用动量包来删除 闪烁?
  • 有没有办法使用较小的Blaze模板来渲染 非反应性的单行?

1 个答案:

答案 0 :(得分:0)

Is there a way to render a loop non-reactively? I've heard there was something like #constant block, but it is no longer supported.

使DOM的一部分非反应非常简单:你只需要使用非反应性助手。例如。在您的模板renderedcreated函数中,您可以将字符串数组附加到模板实例(不是使用this.myStrings = Collection.find()的游标,而是使用this.myStrings = Collection.find().fetch()this的数组作为你的模板实例)。

然后使用return Template.instance().myStrings

将其返回给您的助手
Is there a way to "batch" the whole updating process into a single DOM reflow?

实际上,这取决于您刷新原始数据的方式。上述解决方案应该这样做。请记住,您可以嵌套模板来控制DOM刷新的粒度。另外,请确保您控制订阅,以防它们与相同的已发布内容重叠。您可以使用Template.subscribtionReady()(模板级别)或subscribtion.ready()(子级别)等待每个人准备就绪

Is there a way to use the momentum package to remove the flicker?

如果正确刷新数据,闪烁应该消失。

Is there a way to use a smaller Blaze template to render the single line in non-reactive fashion?

不确定你在这里问什么,但一个好的做法是尝试制作组件级模板,这可能有助于微调DOM渲染。

<div class="line">
{{#each part in line}}
  {{> Part}}
{{/each}}
</div>