【问题标题】:Waiting for template render in Meteor, inconsistent在 Meteor 中等待模板渲染,不一致
【发布时间】:2015-05-13 22:33:57
【问题描述】:

一直在摸不着头脑,所以这是查看它的最简单方法 - 我正在使用这个:

Template.today.rendered = function() {
    console.log(this.firstNode.children.length);
};

只需尝试获取假定呈现的项目数。模板如下所示:

<template name="today">
    <div class="todaySlider">
        {{#each dayOfWeek}}
            {{> singleDay}}
        {{/each}}
    </div>
</template>

如果它很重要,singleDay 看起来像:

<template name="singleDay">
    <div class="day {{isCurrent}}">
        <h2 class="date">{{date}}</h2>

        {{#each items}}
            {{> item }}
        {{/each}}
    </div>
</template>

我正在尝试等待所有“singleDays”呈现,但是我记录的计数在刷新时通常不同。我会得到从 0 到正确值的任何值,我不明白为什么。这似乎是调用它的正确位置,我担心也许双“每个”太慢了?

我已经尝试过计时器(我真的不应该)甚至 DOM Mutation Observers(这看起来有点过头了),但肯定有一个纯粹的 Meteor 方法来解决这个问题,有什么想法吗?

【问题讨论】:

  • 我真的很惊讶这会返回 0 以外的任何值。助手应该在 rendered 回调之后触发,所以在此之前你的 each 将没有任何东西可以迭代和除了最初的div,您的模板将为空。我认为一个更重要的问题是,为什么你需要这个计数。
  • 这不是我特别需要的计数。我实际上正在做的是尝试在“最后一项”上激活一个类,但我使用计数来查看它是否真的在每个“.day”完成渲染。如果结果低于“实际总数”,那对我没有用处。
  • 流星中经常出现这个主题:“我想为这个项目做一些特别的事情”。问题是不清楚“最后一个”在动态更新项目列表中的真正含义。如果您将课程应用于任何给定时间恰好是最后一个项目,会有多糟糕?
  • 没用。顾名思义,这些元素是“天”,我试图将“今天”(总是最后一个)设置为活跃。目前,它可能会将“中间”的某一天设置为活动的,或者根本不设置一个(以及偶尔设置正确的、最近的一天)。不一定要按顺序排列,它们确实有 ID,但我需要先呈现所有“.day”。
  • 啊!我一直在阅读许多关于如何在模板呈现后执行一些 javascript 的类似问题,但没有令人满意的答案。 “.rendered”函数似乎具有“在 DOM 中创建,但未填充内容”的令人困惑和不满意的含义。 (我说的对吗?)模板内容完成时不应该调用一个简单的回调吗?

标签: templates meteor


【解决方案1】:

似乎这里发生的事情是在将 Mongo 集合发送到客户端之前呈现模板。更具体地说,meteor 尽可能快地呈现您的模板,这意味着它没有“等待”任何数据从服务器发送到客户端的概念。因此,如果您在非响应式调用 (Template.rendered) 中间接放置有关数据库查询的任何内容,那么它将以 undefined 的形式使用数据执行。

我假设你的 dayOfWeek 助手看起来像这样:

Template.today.helpers({
  daysOfWeek: function () {
    var today = CollectionName.findOne();

    return today.daysOfWeek;
  }
})

(或者你可能正在使用路由器将一天直接传递给模板)

无论哪种方式,在您的路由器中,您都需要等待 Mongo 集合项发送到客户端,然后才能进行任何渲染。如果您使用 Iron-Router,您只需“等待”您的数据/订阅。

更多信息可以在这里找到:https://github.com/iron-meteor/iron-router/blob/devel/Guide.md#wait-and-ready

如果您仍在使用自动发布,那么您可以将订阅替换为您的数据库查询。

【讨论】:

    【解决方案2】:

    Template.rendered 在模板被渲染时发生,但这并不意味着其中会有任何数据。

    我很确定您需要在帮助程序中执行此操作。

    每个助手不必返回游标,它们也可以返回一个数组。如果“singleDays”的数量很短,您可以将数组发送到模板而不是游标。这有点难看,可能有更好的方法来做到这一点,但我认为这会奏效。

    Template.today.helpers({
        dayOfWeek: function() {
            var days = DaysCollection.find({}).fetch();
            if (days[days.length - 1]) days[days.length - 1].isLast = true;
            return days;
        }
    });
    

    我假设 {{isCurrent}} 是您添加您正在谈论的额外类的位置。如果是这样,只需让 isCurrent 助手查找 this.isLast 是否为真。

    【讨论】:

    • 甜蜜。这确实有效,尽管我偶尔会收到“模板助手中的异常:.dayOfWeek@192.168.13.13:3000/client/controllers/…”,该行是“days[days.length - 1].isLast = true”。一切仍然有效,只是在控制台中弹出。在将此标记为答案之前,我将等待看看是否建议了任何更清洁的解决方案!
    • 如果模板在集合准备好之前运行,days[i] 将是未定义的。在将属性设置为 true 之前,必须检查以确保它存在。我编辑了该行以添加它。
    猜你喜欢
    • 2014-01-16
    • 2017-11-16
    • 2016-04-30
    • 2021-11-09
    • 1970-01-01
    • 2014-12-12
    • 2015-12-22
    • 2018-08-27
    • 1970-01-01
    相关资源
    最近更新 更多