【问题标题】:In Meteor, is there a way to detect when data is fully loaded to the browser?在 Meteor 中,有没有办法检测数据何时完全加载到浏览器?
【发布时间】:2015-07-06 22:16:13
【问题描述】:

这个问题之前可能有人问过,但我似乎找不到一个简单的方法。

我有一个 Meteor 页面,它按时间顺序显示用户发布的消息(最新消息在底部)。我希望页面:

#1) 根据 URL 中提供的参数订阅消息(使用发布/订阅)

#2) 渲染页面

#3) 在页面上显示消息

#4) 滚动到底部。

在开始滚动到底部之前,没有明显的方法可以知道 1、2 和 3 何时完成。 Meteor 确实有一个观察/添加功能,可以在将新消息添加到订阅时执行事件,但这仅在将文档插入 Mongo 时才会触发,并且在向初始订阅显示结果时不会触发。

我将展示上述步骤的代码:

#1:使用发布/订阅订阅消息:在/client/messages.js

Template.messages.created = function() {
  this.autorun( function() {
    this.subscription = Meteor.subscribe("messages", Router.current().params.category);
  }.bind(this));
};

#2 在 /client/messages.html 中渲染页面

<template name="messages">
  {{#each messages}}
    {{messageText}}<br><br>
  {{/each}}
</template>

#3:在页面上显示消息:/client/messages.js

Template.messages.helpers({
  messages: function() {
    var category = Router.current().params.category;
    return Messages.find({category: category}, { sort: { messageDate: 1 } });
  },
});

所有这些都有效,但不会自动滚动到底部。

我无法将 jquery 滚动命令添加到 Meteor onRendered 部分,因为它在数据写入 DOM 之前运行。我可以在滚动到底部之前执行 Meteor.setTimeout 等待 1 秒,但如果使用订阅数据填充 DOM 的时间超过一秒,则不起作用。

还有一个使事情复杂化的事情。我在 URL 中提供 category 变量。当客户端选择另一个类别时,使用 Meteor/Blaze pathFor,

{{pathFor 'messages' channelid='new'}}

浏览器不会重新加载/重新呈现页面,它只是更新触发自动运行的 URL 参数以更改它已订阅的 消息。它只是将新数据写入 DOM。因此,我无法使用 jquery $(document).ready 来检测页面是否准备就绪(因为页面始终准备就绪),并且我不能在我的末尾使用一些花哨的把手,例如 {{scrollToBottom}} {{#each}} 在 messages.html 中,因为它不会重新运行。

那么,有没有一种简单的方法可以检测 Meteor/Blaze 何时将新数据完全写入浏览器?

【问题讨论】:

  • 我怀疑这个问题的答案和我对this question的答案基本相同。渲染隔离几乎总是归结为将onRendered 添加到子模板。
  • Template.messages.rendered = function() { ... }
  • @sbeliv01 和 OP,仅供参考,你们两个似乎在使用旧的 Meteor 代码(这很好 - 您的应用程序可能只是使用早期版本构建的,但只是一个 FYI)。现在是Template.messages.onRendered(function(){ //stuff }) - docs.meteor.com/#/full/template_onRendered
  • Template.messages.onRendered 和 Template.messages.rendered 似乎做同样的事情,至少对我来说。另外仅供参考,Meteor 的“onRendered”并不意味着 html/blaze 完全用数据渲染。这是当 DOM 完成呈现页面时没有数据。这样,页面显示速度很快,然后数据被填充。我想知道当数据填充完成时是否有触发器,例如,当数据游标暂时到达其末尾时。

标签: meteor iron-router


【解决方案1】:

如果我理解正确,您真的只想知道您的所有数据何时从服务器发布到客户端(这样您就可以做一些事情,在这种情况下,滚动到底部)。

Meteor.subscribe() 的所有调用都返回一个订阅句柄。这有一个ready() 方法,告诉你所有的数据已经发送。这包括在模板级别完成的那些(如果适合您的用例,您可能需要考虑)。更多信息在这里: http://docs.meteor.com/#/full/Blaze-TemplateInstance-subscribe

有多种使用方法 - 您需要决定哪种方法适合您。由于ready() 是反应性的,您可以使用它。但是,您可能会发现在订阅中实现 onReady 回调更容易(请参阅上面的文档)。

我怀疑您需要在渲染的模板中实现自动运行。这是为了避免数据在渲染之前到达的相反情况(因此回调触发得太早)。像这样的东西应该可以解决问题(注意您已经在模板创建函数中将订阅句柄设置为this.subscription):

Template.messages.onRendered(function() {
  var self = this;
  this.autorun(function(computation) {
    if(self.subscription.ready()){
      $(document).scrollTop($(document).height());
      computation.stop()
    }
  });
});

这应该确保函数仅在渲染后调用订阅的数据是完整的。如果新文档导致 ready() 不再真实(然后再次准备就绪),执行滚动以停止继续调用后,自动运行也会停止 - 这可能会让页面重新滚动到底部的人感到惊讶!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多