2014-09-06 94 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