我想知道有没有办法知道#each循环是否“就绪”。 “就绪”是指它已渲染所有节点并插入到DOM中。我什至不谈论onRendered回调(旧的rendered)。我试过了

<template name="myTemplate">
<div class="some-class">
    {{#if Template.subscriptionsReady}}
       {{#each messages}}
          <div>{{text}}</div>
       {{/each}}
       <script>
           $(".some-class").trigger("LOOP_READY")
       </script>
    {{/if}}
</div>
</template>


Template.myTemplate.onRendered(function(){
    this.$(".some-class").on("LOOP_READY", doSomething)
})


但这也不起作用。我不想使用计时器。

更新

messages是当前对话框的文本消息的集合,dialogId是存储在Session中的反应变量。

Template.myTemplate.onCreated(function(){
    var self = this;
    self.autorun(function(){
        self.subscribe("messages", Session.get("dialogId"))
    })
})


因此,如果有人更改dialogId,则myTemplate会加载另一条对话框消息,并且我想知道该消息何时准备就绪,才能滚动到特定消息。简单的onReady不起作用,因为在呈现所有消息并获得其自身高度之前,我无法准确地调用scrollTop。

最佳答案

当Spacebars {{#each}}块已将其跨越的每个项目都渲染到DOM中时,没有简单的方法来获得通知。

最好的解决方案是使用另一个反应式计算(Tracker.autorun)来观察消息游标的变化。

每次修改消息列表时,您都可以使用Tracker.afterFlush在完成其他所有反应式计算以执行其工作之后运行任意代码。

{{#each}}块是这些计算之一,其作用是听取您作为参数提供给它的反应性数据源,并将其Template.contentBlock重新渲染为从源中获取的项目重复进行的次数,当前项目为当前数据上下文。

通过侦听与{{#each}}块帮助程序完全相同的反应式数据源,并在其完成自己的反应式计算后运行代码,您可以得到实际的请求行为,而无需依赖某些怪异的setTimeout技巧。

这是此模式的完整实现:

的HTML

<template name="myTemplate">
  <div class="some-class">
    {{#if Template.subscriptionsReady}}
      {{#each messages}}
        <div class="message">{{text}}</div>
      {{/each}}
    {{/if}}
  </div>
</template>


JS

// declare your reactive data source once to reuse the same in multiple places
function messagesCursor(){
  return Messages.find();
}

Template.myTemplate.helpers({
  messages: messagesCursor
});

Template.myTemplate.onRendered(function(){
  this.autorun(function(){
    // we need to register a dependency on the number of documents returned by the
    // cursor to actually make this computation rerun everytime the count is altered
    var messagesCount = messagesCursor().count();
    //
    Tracker.afterFlush(function(){
      // assert that every messages have been rendered
      console.log(this.$(".messages") == messagesCount);
    }.bind(this));
  }.bind(this));
});

07-24 16:56