2012-05-08 73 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,但是它们在被动更新时被删除。 –