0

我有一个应用程序的一部分:

  • 进行 API 调用以将 JSON 对象发送回客户端。此 JSON 对象的属性之一是一个简单的字符串数组。
  • 使用 handlebars.compile 将此数据显示给用户。

这是我正在使用的对象:


{
  _id: new ObjectId("7867867868786786786786786"),
  title: 'rgfregre',
  description: '',
  createdBy: '6687678786786786',
  cards: [ 1, 2, 3 ],
  createdAt: 2021-10-31T02:59:31.496Z,
  updatedAt: 2021-10-31T02:59:31.496Z,
  __v: 0
}

这是把手代码:

    <script id="pack-modal" type="text/x-handlebars-template">
    <div class="modal" id="modal">
        <div class="modal-header">
            <div class="title">\{{title}}</div>
        </div>
        <div class="pack-modal-body">
            <label for="description" class="description-label">Description (optional):</label>
            <textarea name="description" class="pack-description"></textarea>
            <div style="height: 500px;">
            {{#each cards}}
            <h1>??</h1>
            {{/each}}
            </div>
        </div>
    </div>
    <div id="overlay"></div>
    </script>

和 JS 代码虽然它可能在这里没有任何用处

async function openPackModal(packInfo) {
    try {
        const data = await fetch('/get-pack', {
            method: 'POST',
            body: JSON.stringify({ "pack": packInfo }),
            headers: { 'Content-Type': 'application/json' }
        });

        const result = await data.json();
        console.log(result);

        const packModalScript = Handlebars.compile(packModalTemplate);
        const html = packModalScript(result);
        document.body.insertAdjacentHTML('beforeend', html);
        displayModal();
        addCloseModal();
    } catch (err) {
        console.log(err);
    }
}

我可以访问其他所有内容,标题,createdAt 等,但每个循环的卡片根本不起作用。我什至可以用 {{cards}} 替换 {{title}} 并将 [1, 2, 3] 作为 H1,因此我知道车把可以访问它。我还为最新版本的车把添加了 CDN。我必须在标题和其他所有内容前面添加 \ 才能使其正常工作,但是使用卡片循环执行此操作会引发错误。我不知道为什么这不起作用。

4

1 回答 1

0

您的问题是由于您在服务器和客户端上都使用 Handlebars。

您正在使用 Express 运行节点应用程序,并使用 express-handlebars 作为视图引擎。这意味着您的所有 HTML 标记(包括<script>标签)都位于 Handlebars 模板中,这些模板在作为 HTTP 响应发送到客户端之前被执行和插值。

您的客户端代码也使用 Handlebars 从异步加载的数据创建 HTML 片段。这些模板的标记位于您的<script>标签中。问题是这些模板中的 Handlebars 语法已经由您的服务器端 express-handlebars 视图引擎执行。

这就是为什么你必须在你的{{title}}快递前面加上一个斜杠,\. 这告诉服务器端 Handlebars忽略表达式的插值{{title}}并以其原始形式呈现它,{{title}}.

同样,您可以对您的#each呼叫执行相同的操作,如下所示:

\{{#each cards}}
  <h1>??</h1>
\{{/each}}

如果您发现添加所有这些斜线很乏味,Handlebars 提供了对Raw Blocks的支持。原始块将允许您添加一个助手以原始的、未插值的形式输出模板块。

首先,您将在配置 express-handlebars 视图引擎的位置注册帮助程序。例如:

exphbs.create({
  helpers: {
    raw: function () { return options.fn(); }
  }
});

然后你可以在你的模板中使用这个助手,将它包裹在保持原始的块周围(注意四重胡须语法):

<script id="pack-modal" type="text/x-handlebars-template">
  {{{{raw}}}}
    {{title}}
    {{#each cards}}
      <h1>??</h1>
    {{/each}}
  {{{{/raw}}}}
</script>

这将在编写时呈现{{{{raw}}}}标签之间的所有内容,从而无需\在每个 Handlebars 表达式之前添加前缀。

于 2021-11-02T16:21:59.247 回答