Meteor:如何在Mongo数据上执行计算客户端

时间:2014-09-06 20:31:52

标签: javascript html5 mongodb canvas meteor

在我的Meteor应用程序中,我已成功发布数据服务器端并订阅了该数据客户端。现在,我不是将原始数据直接推送到客户端的屏幕,而是将其存储为javascript对象,对其执行一些计算(数字运算),并在客户端的屏幕上呈现结果(在HTML5画布元素中)。每次更新Mongo时,都应该重新运行javascript代码(即重新设置js对象,再次从该对象执行计算,并在画布上呈现新结果)。

我可以使用Template.example.helpers块抓住Mongo数据,并在客户端中直接显示 ,如下所示:


Meteor.subscribe('collection','query');

Template.example.helpers({
  sampleData: function(){
    return Collection.findOne({query:`query`});
  }
});

<template name="example">
  <div>
    {{sampleData.last}}
  </div>
  <canvas id="test-canvas"></canvas>
</template>

但我想要做的是抓住这些数据,然后在Template.example.rendered区块内推送到客户端的屏幕:

Meteor.subscribe('collection','query');

Template.example.rendered = function(){
  // define HTML5 canvas and context variables
  var canvas = $("#test-canvas")[0];
  var context = canvas.getContext("2d");
  // store Mongo data as Javascript variable
  // loop over this variable and perform calculations
    // draw results to the canvas
}

我是以正确的方式接近这个吗?如果是这样,我该如何实现呢?谢谢!

3 个答案:

答案 0 :(得分:0)

可能更容易存储数据并在单独的对象中执行计算并从对象渲染模板而不是直接从mongo渲染,您可以使用&#34; Deps&#34;轻松地保持模板的反应性。它会让你的代码更易于维护。

答案 1 :(得分:0)

你的方法很好。 当集合中的项目为:

时,关键是observe收集和更新画布
  • added(document)addedAt(document, atIndex, before)
  • removed(oldDocument)removedAt(oldDocument, atIndex)
  • changed(newDocument, oldDocument)changedAt(newDocument, oldDocument, atIndex)
  • movedTo(document, fromIndex, toIndex, before)

observe changes in collection还有更高效的方式。 类似下面的代码可以帮助您:

if (Meteor.isClient) {
  Template.example.rendered = function () {
   var canvas = $("#test-canvas")[0];
   var context = canvas.getContext("2d");
   Collection.find().observe({
      added: function (doc) {              // draw sth on canvas          },
      changed: function (doc) {            // draw sth on canvas          },
      movedTo: function (doc) {            // draw sth on canvas          },
      removed: function (doc) {            // remove sth from canvas      }
    });
  };
}

示例:https://github.com/Slava/d3-meteor-basic

答案 2 :(得分:0)

我能够找到自己对上述问题的答案。我的模板在客户端检索数据之前加载了,因此我不断在浏览器的javascript控制台中获取cannot read property <blank> of undefined,代码会中断。您需要使用iron-router包才能

1)设置&#34;数据上下文&#34;您正在处理的模板(打包一个包含该特定模板所需数据源的对象),以及

2)强制模板不要渲染,直到检索到数据。检索数据后,iron-router加载模板,您现在可以对上面创建的数据对象进行完整的javascript控制。

高级别的步骤:

1)安装铁路由器

2)为模板定义路线

3)使用waitOn方法告诉铁路由器您订阅了哪个数据源(它正在等待哪些数据)

4)定义一个&#34; loading&#34;在模板加载之前检索数据时显示的模板(又名启动画面)。根据{{​​3}},您可以通过在您的铁路由器router.js文件中插入此代码块来实现此目的:

Router.onBeforeAction(function(pause) {
  if (!this.ready()) {
    this.render('loading'); // wait
    pause();                // ready
  }
});

只需确保创建loading模板即可。

5)使用data方法为模板设置数据上下文(创建要在模板中使用的数据对象)

详细级别的步骤:

https://github.com/EventedMind/iron-router/issues/554