2012-05-08 71 views
7

我正在嘗試將D3.js可視化文件整合到Meteor應用程序中。頁面加載後,D3函數根據可用數據將DOM元素注入到模板中的<div>防止模板丟棄DOM元素

但是,每當頁面上的任何位置存在被動更新時,流星會轉儲由我的D3.js函數注入的模板內容。我可以重新插入元素,但這會導致不希望的閃爍並降低性能。

任何想法如何抑制外部注入元素的這種下降?我認爲,因爲這些元素最初並不是模板的一部分,所以它們作爲Meteor「清理」過程的一部分被丟棄。

+0

我們需要添加一個很好的方法來保存程序化嵌入的元素。問題是,當一個模板被重新渲染時,它會將DOM中的任何內容替換爲它所呈現的內容 - 它不知道通過其他方式添加了哪些元素。 – dgreensp

+0

@dgreensp - 這是一個功能,而不是缺陷。 ;) – AbigailW

回答

1

隨着0.4.0版本中引入了Spark模板引擎,他們引入了{{#constant}}塊助手來解決這個問題。

http://meteor.com/blog/2012/08/31/introducing-spark-a-new-live-page-update-engine

你的HTML模板應該是這個樣子....

<template name="samplePageTemplate"> 
    <div id="samplePage" class="page"> 
     {{#constant}} 
     <div id="sampleGraph"></div> 
     {{/constant}} 
    </div> 
</template> 

和JavaScript應該是這個樣子......

Template.samplePageTemplate.destroyed = function() { 
    this.handle && this.handle.stop(); 
}; 
Template.samplePageTemplate.rendered = function() { 
    self.node = self.find("svg"); 
    if (!self.handle) { 
     self.handle = Meteor.autorun(function(){ 

      $('#sampleGraph').html(''); 
      renderChart(); 

     }); 
    }; 
}; 

function renderChart(){ 

    // lots of d3 chart specific stuff 

    var vis = d3.select("#sampleGraph").append("svg:svg") 
     .attr("width", window.innerWidth) 
     .attr("height", window.innerHeight) 
     .append("svg:g") 
     .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); 

    // more d3 chart specific stuff 

    }); 
}; 

我已經有時必須使用self.node而不是self.handle,否則它應該相當簡單。

1

你有沒有嘗試給D3注入元素(或至少一個父元素)的唯一ID?從doc(http://docs.meteor.com/#livehtml):

只要確保每個可聚焦元素都具有唯一的ID,或者在最接近的父級中具有唯一的名稱有一個ID。流星將保留這些元素,即使它們的封閉模板被重新渲染,但仍會更新其子項並複製任何屬性更改。

+0

我同意文檔似乎暗示有一個唯一的ID附加到一個元素將防止它被丟棄,但似乎並非如此。在我的應用程序中,插入的每個元素都有唯一的ID,但是它們在被動更新時被刪除。 –