Mustache:在子节中从父节读取变量

20

在Mustache中,是否可以在子节中从父节读取变量?

例如,我想要下面的示例中的{{order_store.id}}从其父级$order_store [(当前子循环的数组索引)] ['id']读取变量。

template.mustache:

{{#order_store}}<table>
    <caption>
        Store Name: {{name}}
        Product Ordered: {{products}}
        Product Weights: {{products_weight}}
    </caption>
    <tbody>
        {{#shipping_method}}<tr>
            <td>
                <input type="radio" name="shipping[{{order_store.id}}]" id="shipping-{{id}}" value="{{id}}" /> 
                <label for="shipping-{{id}}">{{name}}</label>
            </td>
            <td>{{description}}</td>
            <td>{{price}}</td>
        </tr>{{/shipping_method}}
    </tbody>
</table>{{/order_store}}

示例数据(PHP代码);

                $order_store => array(
                array(
                    'id' => 1,
                    'name' => 'Kyriena Cookies',
                    'shipping_method' => array(
                        array(
                            'id' => 1,
                            'name' => 'Poslaju',
                            'description' => 'Poslaju courier'
                        ),
                        array(
                            'id' => 2,
                            'name' => 'SkyNET',
                            'description' => 'Skynet courier'
                        ),
                    ),
                ));
6个回答

8

Mustache不允许您引用父对象。当在子节中时,您想要显示的任何数据都需要包含在子数组中。

例如:

$order_store => array(
array(
    'id' => 1,
    'name' => 'Kyriena Cookies',
    'shipping_method' => array(
        array(
            'id' => 1,
            'name' => 'Poslaju',
            'description' => 'Poslaju courier',
            'order_store_id' => '1'
        ),
        array(
            'id' => 2,
            'name' => 'SkyNET',
            'description' => 'Skynet courier',
            'order_store_id' => '1'
        ),
    ),
));

那么您可以使用标签{{order_store_id}}

在这种情况下,点表示法无法帮助您 - 它不会自动让您访问父数组。(顺便说一句,点表示法并非所有mustache解析器都支持,因此如果将来有任何可能想要将模板与另一种编程语言重用,请尽量避免使用它。)


实际上,我会采纳@sofia的建议并使用Handlebar.js。它与mustache兼容,但添加了一些新功能,如在父上下文中搜索。我曾经遇到过同样的问题,而Handlebar帮助我解决了它,而不需要更改我的json内容。 - Gustavo Cardoso
@GustavoCardoso 这个问题正在寻找 PHP 的答案。 - Michael Mior
我已经在 JavaScript 中尝试过这个,似乎 Mustache 允许我通过引用来引用父对象的属性,如果子对象数组中没有重复的名称(如果有重复,Mustache 将选择来自子对象的属性)。不过我还没有在 PHP 中测试过会发生什么。 - Pere
1
这个答案是不正确的。Mustache确实允许您引用父对象。请参见Rub的答案 - reformed

8

如果要在客户端编译模板,另一个选择是使用HandlebarsJS模板,这些模板与Mustache兼容,并使用父级符号:

{{../order_store.id}}

3

简短回答:既是可以,又是不行。

  • 不行,据我所知,你无法向上访问。
  • 可以,但是需要从顶层开始访问父元素,而非从底部开始。

你需要将所有内容包裹在一个可参考的父元素中,例如本例中的“book”。

var data = { 
"book":{
    title: "The big book",
    author: "Book author",
    chapters: [
       { title: "Hat", color: "black", author: "Chapter 1 author" },
       { title: "Cat", color: "red", author: "Chapter 2 author" }
       ]
   } 
}

var template = document.body.innerHTML;
document.body.innerHTML = Mustache.render(template, data);
<script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.2/mustache.min.js"></script>

{{#book}}
<ul>
    
    Here we have a book titled "{{title}}" with different chapters:
    {{#chapters}}<br><br>
    
    <li>
        Title: {{title}} <br/> 
        Color: {{color}} <br/>
        Chapter Author: {{author}} <br/> 
        
        -- Book Author: {{book.author}} -- <br/> 
    </li>
    {{/chapters}}
</ul>
<span>Author: {{author}}</span>

{{/book}}

玩一下http://jsfiddle.net/pwts7kqx/

<br> Bonus track. Indexed and nested indexing
<br> Title of 1st chapter: {{book.chapters.0.title}}
<br> Title of 2nd chapter: {{book.chapters.1.title}}

3

对于一些Mustache解析器,{{order_store.id}}是必需的。

一个经典的例子是SwaggerCodegen。每个变量的“name”属性都会覆盖模型的“name”属性。在这种情况下,{{../model.name}}会导致错误。我通过以下方式解决了这个问题:

{{name}} // model (parent) name value
{{#vars}}
    {{model.name}} // model (parent) name value
    {{name}}       // vars (child) name valu
{{/vars}}

1

我遇到了同样的问题,出现了空对象但不是null

<div class="photo">
    {{#picture.id}}
        <img src="{{picture.src}}" alt="{{picture.name}}" />
    {{/picture.id}}
</div>

正如您所看到的,我可以在“if”语句中使用picture.src值的picture.id


0

对于Java Mustache,您可以在子范围内仅使用父范围中的字段名称,而无需使用任何斜杠或点号。如果在子范围中没有这样的字段,则会尝试在父范围中查找。

数据结构:

report: {
  footer: 'hello',
  pages: [{
    content: 'blah'    
  }]
}

模板:

{{#pages}}
  <div>{{content}}</div>
  <footer>{{footer}}</footer> <-- that will pull 'footer' field from parent scope
{{/pages}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接