【问题标题】:Handlebars template with JSON data and accessing arrays and objects带有 JSON 数据和访问数组和对象的 Handlebars 模板
【发布时间】:2017-05-01 16:23:31
【问题描述】:

我正在学习车把和 JSON,所以这对某些人来说可能是一个简单的答案。 我有一个 json 文件(基本上是嵌套文件夹的表示。),包括在下面。

我无法理解如何将所有文件夹和子文件夹的路径添加到我的车把模板中。我已经尝试过{{each .}}{{#each folders}} 等,但我要么只得到顶层文件夹,要么什么也没有。任何帮助或指导将不胜感激!

车把:

<ul>
    {{#each folders}}
        <li>{{path}}</li>
    {{/each}}
</ul>

JSON 文件:

{
    "path": "json",
    "folders": [
        {
            "path": "folder-top",
            "folders": [
                {
                    "path": "subfolder1",
                    "folders": [
                        {
                            "path": "sub-subfolder1",
                            "folders": [
                                {
                                    "path": "sub-sub-folder",
                                    "counters": {
                                        "total": 1,
                                        "images": 1,
                                        "files": 1
                                     },
                                     "name": "sub-sub-folder"
                                 }
                             ],
                             "counters": {
                                 "total": 2,
                                 "images": 1,
                                 "folders": 1,
                                 "files": 1
                             },
                             "name": "sub-subfolder1"
                         }
                     ],
                     "counters": {
                         "total": 2,
                         "images": 1,
                         "folders": 1,
                         "files": 1
                     },
                     "name": "subfolder1"
                 }
             ],
             "counters": {
                 "total": 2,
                 "images": 1,
                 "folders": 1,
                 "files": 1
             },
             "name": "folder-top"
         }
     ],
     "counters": {
         "total": 2,
         "images": 1,
         "folders": 1,
         "files": 1
     },
     "name": "json"
}

【问题讨论】:

    标签: arrays json templates recursion handlebars.js


    【解决方案1】:

    您的问题不容易解决,因为正如@Jojo 在another answer 中所说,您需要对未知数量的嵌套文件夹执行{{#each}}。您问题的症结在于:如何递归地应用 Handlebars 模板?

    为了实现我们的递归,我们需要从我们的模板中调用 within 的一块模板;只要我们有要渲染的子文件夹,就一直调用该块。 Handlebars 有partials,它用作可从其他模板调用的可重用模板块。因此,让我们为要应用于每个文件夹的模板创建一个部分:

    <script id="RecursiveFolderPartial" type="text/template">
        <li>
            {{path}}
            {{#if folders}}
                <ul>
                    {{#each folders}}
                        {{> recursiveFolder this}}
                    {{/each}}
                </ul>
            {{/if}}
        </li>
    </script>
    

    请注意,我们的部分调用了部分,recursiveFolder。关键部分是我们将确保使用名称注册我们的部分,recursiveFolder,这样,我们的部分将递归调用自己。

    现在我们已经将大部分模板标记移动到部分模板中,我们模板的唯一工作是通过第一次调用以根文件夹对象作为上下文的部分来获取我们的部分递归:

    <script id="Template" type="text/template">
        <ul>
            {{> recursiveFolder this}}
        </ul>
    </script>
    

    剩下的就是正确连接我们的模板和部分,我们应该准备好了。

    var raw_template = document.getElementById('Template').innerHTML;
    var raw_partial = document.getElementById('RecursiveFolderPartial').innerHTML;
    var template = Handlebars.compile(raw_template);
    
    Handlebars.registerPartial('recursiveFolder', raw_partial);
    

    我创建了一个工作小提琴here

    更新:

    如果您希望呈现当前文件夹的完整路径 - 即当前文件夹路径附加到其父文件夹的路径并用“/”分隔 - 那么您需要将当前路径连接到前一个路径并将结果传递给部分调用。

    让我们首先创建一个 Handlebars 助手来连接字符串:

    Handlebars.registerHelper('concat', function () {
        return Array.prototype.slice.call(arguments, 0, -1).join('');
    });
    

    接下来,我们将更新部分模板以使用parameter,我们将其称为previousPath。我们的部分将输出连接previousPath“/”和当前path的结果。我们还将使用此连接的结果作为部分递归调用的previousPath 参数:

    <li>
        {{concat previousPath '/' path}}
        {{#if folders}}
            <ul>
                {{#each folders}}
                    {{> recursiveFolder this previousPath=(concat ../previousPath '/' ../path)}}
                {{/each}}
            </ul>
        {{/if}}
    </li>
    

    我们还应该更新我们的模板以将previousPath 参数开始为一个空字符串:

    <ul>
        {{> recursiveFolder this previousPath=''}}
    </ul>
    

    可以在here 找到有关此实现的新小提琴。

    【讨论】:

    • 谢谢!这太棒了,我永远也想不通!一个问题,有没有一种直接的方法可以使用它来写入文件夹的完整路径?例如 文件夹顶部/子文件夹 1/子子文件夹 1。我试过{{../path}}/{{path}} 但不行。
    • 使用你的代码我学到了一些关于部分的知识。谢谢。我正在努力解决的一件事是如何仅获取每个文件夹的包含文件夹的名称。我真的很感激任何关于如何整合它的方向。我的大脑开始递归了!
    • @Macsupport:我不确定我理解你的意思。 this 是你要找的吗?
    • 您的解决方案非常混乱,并且有很多不必要的复杂性。 Here 是更好方法的一个例子。
    • @Macsupport:如果我理解您的意思,您只需将 name 值从根对象传递到每个递归调用,就像对 previousPath 和 @ 所做的那样987654346@。下面是一个使用“rootName”作为变量名的例子:jsfiddle.net/76484/vmy5p6j2/8
    【解决方案2】:

    您实际上只迭代对象的第一个维度。因此,如果您知道您的对象有多少维度,请尝试以下操作:

    {{#each folders}}
      {{#each folders}}
        {{#each folders}}
          {{#each folders}}
             ...
          {{/each}}
        {{/each}}
      {{/each}}
    {{/each}}
    

    或者你尝试在一个维度上设置对象。

    无论如何,我不知道如何迭代对象的 n 维。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 1970-01-01
      • 2011-09-18
      相关资源
      最近更新 更多