2015-03-31 95 views
2

我有一个辅助功能正从一个对象的属性(从计算器样本转换)时,做错误检查:{{#if}}是否会影响上下文?

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这是怎么发生的?

+0

这似乎是预期的行为:https://github.com/wycats/handlebars。 JS /问题/ 196。 – 2015-04-10 21:52:05

+0

谢谢,我添加了一条评论,看看我能否弄清楚为什么会发生这种情况。似乎直接与文档冲突... – jt000 2015-04-11 14:01:28

回答

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

块创建新的上下文。所以 - 内部{{#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}} 
相关问题