2014-09-06 104 views
0

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

我可以使用Template.example.helpers块抢蒙戈数据的保持,表明直接在客户端如下:


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> 

但我” m试图做的是在之前推送到客户端的屏幕前抓住这些数据block:

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 
} 

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

回答

0

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

1)设置模板的“数据上下文”你正在工作(包出包含您需要为特定的模板数据源)的对象,并

2)强制模板不要渲染,直到数据被检索。一旦数据被检索,铁路由器加载模板,您现在可以完全控制您在上面创建的数据对象的JavaScript控制。

步骤在一个高级别:

1)安装铁路由器

2)定义为模板

3的路径)使用waitOn方法告诉铁 - 路由器你正在订阅哪个数据源(它正在等待哪个数据)

4)定义一个“加载”模板(aka屏幕),以便在模板加载之前检索数据时显示。按照https://github.com/EventedMind/iron-router/issues/554,您可以通过在铁路由器router.js文件中插入的代码块实现这一点:

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

只要确保你创建一个loading模板与此一起去。

5)使用data方法来设置的数据上下文模板(创建该数据对象,以在模板在一个详细的级别使用)

步骤:

http://www.manuel-schoebel.com/blog/iron-router-tutorial

0

它可能更容易存储数据和执行计算在一个单独的对象,并从对象呈现模板,而不是从mongo直接,你可以很容易地让你的模板使用“Deps”反应,它会使你的代码更易于维护。

+0

您能否提供一些代码示例以解释您的解释?我仍然在学习流星,所以我在回复时遇到了一些麻烦。谢谢! – 2014-09-06 20:44:19

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)

有也更pe高效的方式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

+0

嘿库巴 - 这似乎很适合作为整体监控文件。但是,如何处理WITHIN文档中的更改?我正在尝试监视对现有文档的更改(文档数量已修复) - 有何建议?我想存储添加/删除的值客户端,所以我可以对它们进行计算。 – 2014-09-06 21:44:27

+0

请参阅[文档](http://docs.meteor.com/#observe)。还有一些处理程序,如:'changed','movedTo'。另请看[observeChanges](http://docs.meteor.com/#observe_changes) – 2014-09-07 12:59:21