Meteor 中的模板级反应性
Template level reactivity in Meteor
我正在解决一个问题,我想在仪表板中将数据显示为图表(通过 perak:c3) and in a table (via aslagle:reactive-table). My issue is that the data is pulled from a collection in MongoDB, and it's format is instantly amenable to plotting via c3, but needs to be transformed into a local collection to be used by the reactive-table package, as suggested in 上一个问题。
当我更改要显示的数据集时,我希望更新图表,table 也更新。这需要更改本地集合中的值,但是,这会减慢速度,因此不是平滑地重新绘制图表,而是在页面上冻结,然后显示新数据。
我已经创建了一个示例项目 on GitHub here 因此可以很容易地重现该问题。如果您在浏览器中 运行 应用程序和 select 数据集,您就会明白我的意思
要查看我想在图表中保留的反应行为,请转到 client/templates/dashboard/dashboard.html
并简单地注释掉 table 模板 {{> dashboardTable}}
现在更改数据集以查看图表如何平滑地重新绘制。本质上,我试图确保模板 dashboardChart
和 dashboardTable
相互独立呈现。
更新
遵循 Michael Floyd 的 使用超时的建议有点帮助
Meteor.setTimeout(function(){createLocalCollection(data)},200);
虽然图表绘制顺利,但当 table 完成填充时,图表会再次绘制。看起来它跳转到了一些我无法理解的中间状态。 Here is a video 表达我的意思。
记住js是单线程的。你有两件事要做,它们将按顺序发生。您可以做的是延迟 使用Meteor.setTimeout()
更新本地集合的代码。这将允许图表先更新,然后您的 table 可以更新。我之前看到过这个 运行 一个更新 DOM 的函数(在你的情况下 d3 正在更新 svg canvas)但是实际的屏幕更新滞后了很长时间 运行ning js.
我专门试过这个,图表表现很好。
Meteor.setTimeout(function(){createLocalCollection(data)},500);
将时间间隔减少到 100 允许图表更新,但菜单不会完全淡出,直到本地集合完成更新。
我在 tables 和本地集合中使用的一件事是仅在屏幕上呈现相应的非本地文档时更新本地集合文档(假设有一个 1:1 原始数据和转换版本之间的关系)。这允许反应式 table 延迟加载。
我将其添加为单独的答案,因为这是一种完全不同的方法。
在 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 告诉您图表渲染何时完成,然后您的 table 可以开始填充。结果是瞬时图表更新,然后是 table 更新。也没有超时问题。
我正在解决一个问题,我想在仪表板中将数据显示为图表(通过 perak:c3) and in a table (via aslagle:reactive-table). My issue is that the data is pulled from a collection in MongoDB, and it's format is instantly amenable to plotting via c3, but needs to be transformed into a local collection to be used by the reactive-table package, as suggested in
当我更改要显示的数据集时,我希望更新图表,table 也更新。这需要更改本地集合中的值,但是,这会减慢速度,因此不是平滑地重新绘制图表,而是在页面上冻结,然后显示新数据。
我已经创建了一个示例项目 on GitHub here 因此可以很容易地重现该问题。如果您在浏览器中 运行 应用程序和 select 数据集,您就会明白我的意思
要查看我想在图表中保留的反应行为,请转到 client/templates/dashboard/dashboard.html
并简单地注释掉 table 模板 {{> dashboardTable}}
现在更改数据集以查看图表如何平滑地重新绘制。本质上,我试图确保模板 dashboardChart
和 dashboardTable
相互独立呈现。
更新
遵循 Michael Floyd 的 使用超时的建议有点帮助
Meteor.setTimeout(function(){createLocalCollection(data)},200);
虽然图表绘制顺利,但当 table 完成填充时,图表会再次绘制。看起来它跳转到了一些我无法理解的中间状态。 Here is a video 表达我的意思。
记住js是单线程的。你有两件事要做,它们将按顺序发生。您可以做的是延迟 使用Meteor.setTimeout()
更新本地集合的代码。这将允许图表先更新,然后您的 table 可以更新。我之前看到过这个 运行 一个更新 DOM 的函数(在你的情况下 d3 正在更新 svg canvas)但是实际的屏幕更新滞后了很长时间 运行ning js.
我专门试过这个,图表表现很好。
Meteor.setTimeout(function(){createLocalCollection(data)},500);
将时间间隔减少到 100 允许图表更新,但菜单不会完全淡出,直到本地集合完成更新。
我在 tables 和本地集合中使用的一件事是仅在屏幕上呈现相应的非本地文档时更新本地集合文档(假设有一个 1:1 原始数据和转换版本之间的关系)。这允许反应式 table 延迟加载。
我将其添加为单独的答案,因为这是一种完全不同的方法。
在 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 告诉您图表渲染何时完成,然后您的 table 可以开始填充。结果是瞬时图表更新,然后是 table 更新。也没有超时问题。