{{#if}}会影响上下文吗?

时间:2015-03-31 19:34:28

标签: handlebars.js assemble

我有一个辅助函数,在从对象获取属性时执行错误检查(从stackoverflow上的示例转换):

module.exports.register = function (Handlebars, options) {

  Handlebars.registerHelper('get', function (obj, prop, context) {
    if (typeof obj !== 'object') {
      throw new Error('get: Cannot get from ' + typeof obj);
    }

    if (typeof prop !== 'string') {
      throw new Error('get: Property must be a string. Type ' + typeof prop + ' not supported');
    }

    if (!obj.hasOwnProperty(prop)) {
      throw new Error('get: Object does not contain the property "' + prop + '"');
    }

    return obj[prop];
  });
}

当我正常使用它时效果很好:

<div>
  {{get ../site.sectionNames tag}}
</div>

...但是,如果我将其放在{{#if true}}元素中,则obj未定义:

<div>
  {{#if true}}
    {{get ../site.sectionNames tag}}
  {{/if}}
</div>

我的印象是{{#if}} doesn't change the context为什么会这样?

2 个答案:

答案 0 :(得分:1)

请考虑以下示例 ..

<强>上下文

{
  id: 1,
  items: ['a', 'b']
}

模板1:

{{#each items}}
  <div>outer: {{../id}}</div>
  {{#if ../id}}
    <div>inner: {{../id}}</div>
  {{/if}}
{{/each}}

输出:

outer: 1  
inner:  
outer: 1  
inner:  

模板2: - (没有外部#each块)

<div>outer: {{id}}</div>
{{#if id}}
    <div>inner: {{id}}</div>
{{/if}}

输出:

outer: 1
inner: 1 

所以,我认为#each会造成这种不一致。

../为我们提供了当前块之外的上下文,而不是JSON中的父上下文。对于#if块,内部和外部上下文可能相同也可能不同。

因此,为了保持一致并避免任何混淆,我们应始终添加../来引用#if块内的值。
例如,

{{#if id}}
   {{../id}}
{{/if}}

答案 1 :(得分:1)

Blocks创建一个新的上下文。所以 - 内部{{#if}}位于{{#each}}的上下文中 - 而不是根上下文。

换句话说,您可以使用:

{{#each items}}
    <div>outer: {{../id}}</div>
    {{#if ../id}}
        <div>inner: {{../../id}}</div>
    {{/if}}
{{/each}}

您还可以尝试@root

{{#each items}}
    <div>outer: {{ @root.id}}</div>
    {{#if @root.id}}
        <div>inner: {{ @root.id}}</div>
    {{/if}}
{{/each}}