在 Meteor/Blaze 中呈现静态 HTML

Rendering static HTML in Meteor/Blaze

我一直在尝试将静态 HTML+JavaScript 包含在 Meteor / Telescope (telesc.pe) 应用程序中,但无法使用 Blaze。

为了创建一个比我的原始案例更简单的案例,我尝试在 via Meteor 中插入一个简单的 HTML + javascript 代码块(非常基本的 D3.js 创建一个圆的可视化)在下面。此 HTML 块存储在 MongoDB 中的集合中,并使用下面的模板访问

<script type="text/javascript" src="http://mpld3.github.io/js/mpld3.v0.2.js"></script>
  <h1>Circle</h1>
    <div id="viz"></div>
  <h1>/Circle</h1>
    <script type="text/javascript">

    var sampleSVG = d3.select("#viz")
        .append("svg")
        .attr("width", 100)
        .attr("height", 100);

    sampleSVG.append("circle")
        .style("stroke", "gray")
        .style("fill", "white")
        .attr("r", 40)
        .attr("cx", 50)
        .attr("cy", 50)
        .on("mouseover", function(){d3.select(this).style("fill", "aliceblue");})
        .on("mouseout", function(){d3.select(this).style("fill", "white");});

    </script>

我一直将它作为未转义的标记包含在 Meteor 中。例如

<template name="post_body">
  {{{ htmlBody }}}
</template>

上面代码片段中的 HTML 正确呈现(文本 Circle 和 /Circle),但它似乎没有尝试加载我包含的任何 javascript 元素。

我完全知道这不是将可视化加载到 Meteor 应用程序的最佳方式,但很可能需要这样做,因为我正在使用的(更复杂的)可视化是使用静态生成的外部应用程序。

如能提供有关如何实现此功能的任何帮助,我们将不胜感激!

您不能在 Meteor 模板中使用 <script> 标签。 Meteor 解析您的模板以将其作为 DOM 对象呈现到 DOM 中,并且不执行任何内联 JavaScript.

也就是说,实现您想要做的事情非常容易。首先,走这条线:

<script type="text/javascript" src="http://mpld3.github.io/js/mpld3.v0.2.js"></script>

并将其放入 index.html 文件的 <head> 中,或者将 HTML 文件作为您应用程序的入口点。

接下来,将内联 script 块中的代码放入模板的 rendered 回调中:

Template.post_body.rendered = function() {
    var sampleSVG = d3.select("#viz")
        .append("svg")
        .attr("width", 100)
        .attr("height", 100);

    sampleSVG.append("circle")
        .style("stroke", "gray")
        .style("fill", "white")
        .attr("r", 40)
        .attr("cx", 50)
        .attr("cy", 50)
        .on("mouseover", function(){d3.select(this).style("fill", "aliceblue");})
        .on("mouseout", function(){d3.select(this).style("fill", "white");});
};

它将在模板呈现到 DOM 后执行,如您所愿。为了提高性能,您可以考虑将 d3.select 替换为 this.findrendered 中的 this.findAll,以将 DOM 搜索限制为仅模板上下文。参见 http://docs.meteor.com/#/full/template_find

如果你直接从你的数据库中处理一个可怕的 HTML 块,它有你的样本中的 <script> 标签,你需要先将它解析为一个字符串。使用正则表达式找到第一个 script 标签的 src (我会让你找到许多其他关于如何做到这一点的 SO 答案)并使用 jQuery 的 $.getScript 动态加载该脚本。使用另一个正则表达式提取内联脚本块,并将其作为回调传递给 $.getScript。尽管我很讨厌这么说,但你必须使用 eval:

Template.post_body.rendered = function() {
    $.getScript(urlThatYouParsed, function() { eval(codeThatYouParsed); });
};