【问题标题】:Meteor - {{#each}} in template loads old data first, then reloadsMeteor - 模板中的 {{#each}} 先加载旧数据,然后重新加载
【发布时间】:2014-04-14 07:48:02
【问题描述】:

我在 gnf.meteor.com 上有一个 Meteor 应用程序,用于在我家的商店运行的项目中进行捐赠活动。该应用程序本身与这个问题不太相关,但它提供了简单的信用卡结账功能,可以连接到贝宝,并为我们跟踪生成的交易日志和余额。

我的应用程序中与此问题相关的页面是https://gnf.meteor.com/log。此页面记录了网站上的最新捐赠、捐赠者、类型、金额和接受者。

当您第一次在 /log 加载或重新加载页面时,Meteor 需要 7-10 秒才能呈现正确的数据。在此间隔期间,它首先显示一个空列表,然后在几秒钟后它会显示一些较旧的记录(不是最新数据),最后它会使用正确的记录重新渲染。我猜可能集合被渲染,然后排序,然后重新渲染,但我不知道这是否真的是一个排序问题,它可能只是先加载旧记录,在加载完成之前渲染。

为了说明我的意思,加载页面并观察在撰写本文时最新的捐赠(列表顶部)应该是“Maura M. $70 -> Suzie Murphy”。 (这个应用程序还没有被大量使用,所以它会在一段时间内保持最新的交易。)

如果可能,我想避免这种情况,并且我还计划根据this question 的提问者的要求引入加载消息。

我也讨厌一开始加载需要很长时间,尽管我的交易集合中只有大约 300 条记录。也许我可以以某种更有效的方式实现相同的查询?

这是我的应用程序中的相关代码:

在我的 Javascript 中:

Data = {
  funds         : new Meteor.Collection('funds'),
  transactions  : new Meteor.Collection('transactions')
};

// ...

Template.logPage.latestDonations = function() {
  return Data.transactions.find({
    $or : [{ type : 'donation' }, { type : 'deposit' }]
  }, {
    sort : { timestamp : -1 },
    limit : 50
  });
};

Template.logPage.typeDonation = function() {
  return this.type == "donation";
};

Template.logPage.typeDeposit = function() {
  return this.type == "deposit";
};

在我的 HTML 中:

<template name="logPage">
  <h1 class="underline">Latest 50 Donations <small>(updates in real time)</small>&nbsp;&nbsp;</h1>
    {{#each latestDonations}}
        <h2>
            {{donorName}} &nbsp;
            {{#if typeDonation}}
                <i class="fa fa-credit-card"></i>
            {{/if}}
            {{#if typeDeposit}}
                <i class="fa fa-money"></i>
            {{/if}}
            &nbsp;${{amount}}&nbsp;&nbsp;<i class="fa fa-arrow-right"></i>
            &nbsp; <a href="/fund/{{fund_id}}">{{recipientName}}</a>
            <small><abbr class="timeago" title="{{donationTimestamp}}">
                {{donationTimeString}}</abbr>
            </small>
        </h2>
    {{/each}}
</template>

提前感谢任何人可能拥有的任何见解。 Meteor 很棒,但这些小烦恼让我很沮丧。

【问题讨论】:

    标签: javascript performance mongodb templates meteor


    【解决方案1】:

    针对您的问题的一些建议

    1) 编辑你的服务器端发布功能(我假设你有这个并且没有使用自动发布包)只发布 50 使用时间戳进行排序。这将向客户端发送更少的数据,并且只发送您实际要使用的数据。您只需将您的查找查询移动到您可能有没有任何属性的查找查询的服务器.find({})

    2) 钩入集合的.ready() 方法以确定何时可以显示它。当所有数据都加载到客户端时,这将返回 true。您看到的是空的,然后是部分的,然后是完整的渲染,因为您的代码没有等待所有数据,而是在数据到达时渲染。这不是一件坏事,但并不总是可取的。您可以使用类似 https://github.com/oortcloud/unofficial-meteor-faq#how-do-i-know-when-my-subscription-is-ready-and-not-still-loading 的方式推出自己的解决方案,但我建议将 Iron-router 与相关路由 https://github.com/EventedMind/iron-router#waiting-on-subscriptions-waiton 的 waitOn 功能结合使用,当它与 loadingTemplate 选项结合使用时,您可以制作一个加载时出现漂亮的(正在加载...)消息,然后立即转换到完全填充的模板

    【讨论】:

    • 非常感谢!我已经在使用 Iron-router,所以我肯定会使用 waitOn 功能,我不知道。
    • 至于更改我的发布功能,对于不同的视图,它是如何工作的?我需要为显示的其他页面发布整个集合,即基金的整个交易历史。我可以将所有集合发布到一个模板,并将部分集合发布到另一个模板吗?
    • 是的,完全正确 - 只是以不同的方式命名出版物 - 您可以拥有同一个集合的多个出版物,并且流星将在客户端合并它们 - 一种流行的模式将有 2 个出版物,例如 recentTransactions(last 50)和 fundDetails(基金 + 该基金的所有交易 - 请参阅 docs.meteor.com/#meteor_publish 以在 1 个发布中从集合中返回 2+ 个查询结果) - 为了进一步优化,您可以使用 fields 属性仅发送您的内容需要每个出版物 - 然后您可以将每个出版物附加到特定的模板/路线
    • 好的,太好了!对不起,我还在学习流星。如何将特定出版物附加到路由?
    • 使用waitOn 附加订阅,然后使用data 从查询返回结果 - 请参阅github.com/EventedMind/iron-router#data
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 2014-02-22
    • 1970-01-01
    • 2016-09-05
    • 2016-10-01
    • 2016-08-15
    • 1970-01-01
    相关资源
    最近更新 更多