{{#each}}和微调器DOM计时

时间:2015-12-14 19:12:19

标签: meteor

我有大约150个带有各种过滤器/排序的条目。 默认情况下,当我有10个显示的响应时间是正常的(它不是慢JS代码,因为限制为10是作为最后一步完成)。 但是当我按下展开按钮时,显示所有条目需要2秒。 同时应用过滤器/排序等。

{{#each}}中使用的助手是ReactiveVar,它返回数组。 我想在重新渲染#each之前显示微调器,并在完成后将其关闭。 如果它等待每一步完成并且还更新DOM,那么像这样的伪代码。

Tracker.autorun ->
  spinner.set(true)
  showFeed.set(resultFeed.get())
  spinner.set(false)

但是,如果我不使用Meteor.setTimeout来推迟showFeed.set,则永远不会显示微调器。我不想依赖setTimeout。但我不明白整个flush()afterFlush()足以将其拉下来。在继续下一步之前,我如何计时等待完成所有这些步骤(也使用DOM更新)?

1 个答案:

答案 0 :(得分:0)

我不确定如何在DOM更新时显示微调器,但我想建议您另一个选择:您可以通过隐藏/显示DOM节点而不是创建/销毁它们来提高DOM更新性能。< / p>

让我举个例子:

昂贵的DOM更新(创建/销毁):

HTML:

<template name="items">
  {{#each filteredItems as item}}
    <div class="item">
      {{item.content}}
    </div>
  {{/each}}
</template>

COFFEE:

Template.helpers.items
  filteredItems: -> Session.get('filteredItems')

onFiltering ->
  Session.set('filteredItems', computeFilteredItems());

为什么要这么费力?因为每次进行过滤时,Blaze都会创建/销毁DOM节点,而这种操作相当费力。

便宜的DOM更新(显示/隐藏):

HTML:

<template name="items">
  {{#each allItems as item}}
    <div class="item {{#if isItemVisible item}}item--visible{{/if}}">
      {{item.content}}
    </div>
  {{/each}}
</template>

COFFEE:

Template.helpers.items
  allItems: -> allItems
  isItemVisible: -> Session.get('filteredItemsIds').indexOf(item._id) !== -1

onFiltering ->
  Session.set('filteredItemsIds', computeFilteredItems().map((item) -> item._id))

CSS:

.item {
  display: none;
}

.item--visible {
  display: block;
}

为什么便宜?由于不会动态创建/销毁DOM节点,因此将在第一次渲染时创建所有必需的节点。我们只是动态地添加/删除CSS类,这种操作比创建/销毁更便宜。

P.S。我没有完成任何测试,所以我不是100%肯定,但它应该可以工作。