如何在hbs视图模板内的<script>标记内定义数组

时间:2017-02-18 12:20:02

标签: arrays node.js express handlebars.js

我正在通过构建来自这个 FreeCodeCamp挑战。我正在使用Chart.js在前端的饼图上显示用户投票。要显示chart.js所需的投票数据是通过在Handlebars(hbs)视图模板中添加内联脚本来提供的。

&#xA;&#xA;

以下是该视图的摘录:

&#xA;&#xA;
 &lt; li class =“list__item民意调查行“id =”民意调查 -  {{this.id}}“&gt;&#xA; &LT;脚本&GT;&#XA; Pollstack.chartData.push({&#xA;“id”:“{{this.id}}”,&#xA;“type”:“{{this.type}}”,&#xA;“数据集” :{&#xA;“选项”:{{this.options}} //问题此处&#xA;}&#xA;});&#xA; &LT; /脚本&GT;&#XA;&#XA; &lt; div class =“poll__query col-sm-12 col-md-6”&gt;&#xA; &lt; p class =“poll__question”&gt; {{this.topic}}&lt; / p&gt;&#xA; &lt;! - 这里有更多标记来显示选项 - &gt;&#xA; &lt; / div&gt;&#xA;&lt; / li&gt;&#xA;  
&#xA;&#xA;

选项(带注释的JS行)是一个数组我从MongoDB数据库中检索的对象。这方面的一个例子是:

&#xA;&#xA;
  [&#xA; {&#XA; _id:29302839023,&#xA; optionText:“Karl Marx”,&#xA;票数:12&#xA; },&#XA; {&#XA; _id:5454523231,&#xA; optionText:“Virginia Woolf”,&#xA;票数:14&#xA; },&#XA; {&#XA; _id:94895989348,&#xA; optionText:“Thomas Hobbes”,&#xA;票数:10&#xA; }&#xA;]&#xA;  
&#xA;&#xA;

我想通过外部JavaScript脚本访问前端的这个选项数组说: app的.js 。但这就是我在前端所得到的:

&#xA;&#xA;

&#xA;&#xA;

我有两个问题,我将非常感谢任何回答这些问题的人:

&#xA;&#xA;
    &#xA;
  1. 如何渲染数组而不是那个[object Object],[object Object] string?
  2. &#xA;
  3. 有没有更好的方法(最佳实践)将数据传递给前端JS而不是使用内联脚本?
  4. &#xA;
&#xA;&#xA;

感谢阅读。

&#xA;

2 个答案:

答案 0 :(得分:1)

Handlebars&#39;工作是用文本替换胡须标签{{...}}。当您为Handlebars提供一个复杂的对象(如数组)时,它只能调用该对象的.toString()方法并返回结果。这就是你在标记中得到[object Object],[object Object],[object Object]的原因,这是你的数组的弦乐版本。

您必须记住,您的模板正在生成文本,而不是JavaScript。它不会在客户端加载并解析此文本之前将其视为JavaScript。这意味着没有对象引用的概念,只有字符串。就像您明确地将idtypedatasets属性写入模板一样,您需要显式编写将被解析为options数组的文本;使用Handlebars库来帮助您进行迭代和插值。结果如下所示:

{
    "id": "{{id}}",
    "type": "{{type}}",
    "datasets": {
        "options": [
            {{#each options}}
                {
                    "id": {{_id}},
                    "optionText": "{{optionText}}",
                    "votes": {{votes}}
                }
                {{#unless @last}},{{/unless}}
            {{/each}}
        ]
    }
}

如果这看起来有点冗长,还有另一种选择。我们上面所做的是创建复杂JavaScript对象的字符串表示。这与JSON.stringify()方法的目标相同。或者,我们可以在控制器中JSON.stringify我们的数据,并在模板中的方法调用中呈现结果。我们需要记住使用三重胡须,以便我们的结果不会被HTML转义。

我们控制器中的视图模型将更新为包含我们的Pollstack数据的字符串化JSON版本:

pollstack_data: JSON.stringify({
    "id": id,
    "type": type,
    "datasets": {
        "options": options
    }
})

然后我们的视图只需渲染此字符串而不转义双引号:

Pollstack.chartData.push({{{pollstack_data}}});

答案 1 :(得分:1)

将数组编码为控制器端的urlencoded JSON字符串,并在视图侧对其进行解码以恢复数组。

控制器

var options = [
     {
     _id: 29302839023,
     optionText: "Karl Marx",
     votes: 12
    },
    {
     _id: 5454523231,
     optionText: "Virginia Woolf",
     votes: 14
    },
    {
     _id: 94895989348,
     optionText: "Thomas Hobbes",
     votes: 10
    }
]

options = encodeURI(JSON.stringify(options));

视图

<li class="list__item poll row" id="poll-{{this.id}}">
  <script>
    Pollstack.chartData.push({
      "id": "{{this.id}}",
      "type": "{{this.type}}",
      "datasets": {
        "options": JSON.parse(decodeURI("{{this.options}}"))
      }
    });
  </script>

  <div class="poll__query col-sm-12 col-md-6">
    <p class="poll__question">{{this.topic}}</p>
    <!-- some more markup here to display the options -->
 </div>
</li>