【问题标题】:Template level reactivity in MeteorMeteor 中的模板级反应性
【发布时间】:2016-05-15 15:41:11
【问题描述】:

我正在解决一个问题,我想在仪表板中以图表(通过perak:c3)和表格(通过aslagle:reactive-table)的形式显示数据。我的问题是数据是从 MongoDB 中的集合中提取的,它的格式可以立即通过 c3 进行绘图,但需要转换为由响应表包使用的本地集合,如 this answer 中所建议的那样上一个问题。

当我更改要显示的数据集时,我希望更新图表和表格。然而,这需要更改本地集合中的值,这会减慢速度,因此不是平滑地重绘图表,而是页面冻结,然后显示新数据。

我创建了一个示例项目on GitHub here,因此可以轻松复制问题。如果你运行应用程序并在浏览器中选择一个数据集,你会明白我的意思

要查看我想在图表中保留的反应行为,请转到 client/templates/dashboard/dashboard.html 并简单地注释掉表格模板 {{> dashboardTable}}

现在更改数据集以查看图表如何平滑重绘。本质上,我试图确保模板dashboardChartdashboardTable 彼此独立呈现。


更新

遵循 Michael Floyd 的关于使用超时的建议有所帮助

Meteor.setTimeout(function(){createLocalCollection(data)},200);

虽然图表绘制得很顺利,但是当表格填满后,图表又会重新绘制。看起来它跳到了一些我无法理解的中间状态。 Here is a video 表达我的意思。

【问题讨论】:

  • 该 HTML 注释并不能真正阻止呈现模板 - 请改用 blaze 注释:{{!-- comment --}}

标签: javascript meteor d3.js meteor-blaze meteor-helper


【解决方案1】:

我将此作为单独的答案添加,因为它是一种完全不同的方法。

使用 d3 中的 onRendered 回调调用本地集合更新。

你在哪里:

chart = c3.generate({
  bindto: '#dataset-chart',

dashboard_chart.js,添加:

chart = c3.generate({
  onrendered: createLocalCollection(),
  bindto: '#dataset-chart',

当然,您需要从事件处理程序中删除 createLocalCollection(data)

为了避免必须通过 d3 中的 onrendered 处理程序传递数据上下文,还请更新您的 createLocalCollection 函数以使用您之前定义的反应变量 datasetID 来建立当前数据集:

var createLocalCollection = function() {
    var values = My_First_Collection.find({datasetID: datasetID.get()}).fetch();
    var tempDoc = {};
    local.remove({});
    tempDoc = {};
    for (var i in values[0].value) {
      tempDoc.value = values[0].value[i];
      tempDoc.date = values[0].date[i];
      local.insert(tempDoc);
    }
};

使用此方法,您可以让 D3 告诉您图表渲染何时完成,然后您的表格可以开始填充。结果是瞬时图表更新,然后是表格更新。也没有超时。

【讨论】:

  • 顺便说一下,您可能需要重新考虑本地收集方法。最昂贵的方面是local.insert() 一方面,您可以通过datasetID 索引该集合,这样您就不需要每次都重新构建它,其次您可以在用户查看当前图表时缓存其他图表
  • 非常感谢。我还确保通过在Meteor.startup() 块中包含My_First_Collection._ensureIndex({ "datasetID" : 1}) 来对datasetID 进行索引。桌子还有延迟,但我现在可以忍受。感谢您的帮助和洞察力。
【解决方案2】:

记住js是单线程的。你有两件事要做,它们将依次发生。您可以做的是延迟使用Meteor.setTimeout() 更新本地集合的代码。这将允许图表首先更新,然后您的表格可以更新。我之前在运行一个更新 DOM 的函数(在你的情况下 d3 正在更新 svg 画布)之前看到过这种情况,但实际的屏幕更新却卡在了长时间运行的 js 后面。

我专门试过这个,图表表现很好。

Meteor.setTimeout(function(){createLocalCollection(data)},500);

将时间间隔减少到 100 允许图表更新,但随后菜单不会完全淡出,直到本地集合完成更新。

我对表格和本地集合使用的一件事是仅在屏幕上呈现相应的非本地文档时更新本地集合文档(假设原始数据和转换后的数据之间存在 1:1 的关系版本)。这允许响应式表延迟加载。

【讨论】:

  • 所以我尝试使用updatePlot(data); Meteor.setTimeout(createLocalCollection(data), 5000);,而不是updatePlot(data); createLocalCollection(data);,但这没有效果,无论使用的超时时间长短
  • 我将不得不深入研究您的代码,看看我能找到什么。
  • setTimeout 将函数作为第一个参数。您只需匿名拨打createLocalCollection
  • 如果我增加超时,这对我有用。出于某种原因,随着200 的超时,图表被绘制出来,然后当表格完成填充时,图表再次被绘制。它看起来列表它跳转到一些我无法理解的中间状态。
  • 很高兴它有效!您需要的超时时间可能取决于机器速度。
猜你喜欢
  • 2013-04-14
  • 1970-01-01
  • 2014-06-20
  • 2013-06-19
  • 2017-03-06
  • 2014-07-09
  • 1970-01-01
  • 2014-03-12
  • 2016-03-11
相关资源
最近更新 更多