把手 - 是否可以在部分中访问父上下文?

时间:2012-02-23 10:50:06

标签: javascript templates handlebars.js

我有一个车把模板,可以加载一个子元素的部分。

我需要从部分内部调用模板中的父上下文中访问变量。 ..似乎无法解决部分内容。

简化代码如下:

模板

    {{#each items}} 
        {{> item-template}}
    {{/each}}

部分

    value is {{value}}

(显然真正的代码更复杂,但它是相同的原则,在部分..内似乎未定义。)


为了表明它未定义,我使用了一个非常简单的助手whatis,如下所示:

Handlebars.registerHelper('whatis', function(param) {
    console.log(param);
});

并将上述代码更新为:

更新模板

    {{#each items}} 
        {{whatis ..}}  <-- Console shows the correct parent context
        {{> item-template}}
    {{/each}}

更新了部分

    {{whatis ..}}  <-- Console shows "undefined"
    value is {{value}}

有没有办法解决这个问题?我错过了什么吗?

编辑: handlebars' github project

上存在与此问题相关的未解决问题

8 个答案:

答案 0 :(得分:39)

以防万一有人偶然发现这个问题。此功能现在存在于Handlebars中。

这样做:

{{#each items}} 
    {{! Will pass the current item in items to your partial }}
    {{> item-template this}} 
{{/each}}

答案 1 :(得分:22)

工作小提琴(灵感来自AndrewHenderson的车把拉动请求#385) http://jsfiddle.net/QV9em/4/

Handlebars.registerHelper('include', function(options) {
    var context = {},
        mergeContext = function(obj) {
            for(var k in obj)context[k]=obj[k];
        };
    mergeContext(this);
    mergeContext(options.hash);
    return options.fn(context);
});

以下是您设置父模板的方式:

{{#each items}} 
    {{#include parent=..}}
        {{> item-template}}
    {{/include}}
{{/each}}

部分:

value is {{parent}}

答案 2 :(得分:9)

截至 2.0.0 partials now supports passing in values

{{#each items}}
    {{> item-template some_parent_var=../some_parent_var}}
{{/each}}

我花了一段时间才发现这一点,希望它对其他人也有用!

答案 3 :(得分:3)

您可以在链接到github的评论中使用一些建议的解决方案:

https://github.com/wycats/handlebars.js/issues/182#issuecomment-4206666
https://github.com/wycats/handlebars.js/issues/182#issuecomment-4445747

他们创建帮助程序以将信息传递给部分。

答案 4 :(得分:3)

将父上下文传递给partial的最简单方法是在partial内部执行循环。这样,默认情况下会传递父上下文,当您在部分内部执行循环时,{{../variable}}约定可以访问父上下文。

example fiddle here

数据

{
  color: "#000"
  items: [
    { title: "title one" },
    { title: "title two" },
  ]
}

模板

<div class="mainTemplate">
  Parent Color: {{color}}
  {{> partial}}
</div>

部分

<div>
  {{#each items}}
    <div style="color:{{../color}}">
      {{title}}
    </div>
  {{/each}}
</div>

答案 5 :(得分:2)

我创建了一个每个Helper函数,其中包含关键parentContext下的子上下文中的父键/值。

http://jsfiddle.net/AndrewHenderson/kQZpu/1/

注意:下划线是一种依赖。

Handlebars.registerHelper('eachIncludeParent', function ( context, options ) {
var fn = options.fn,
    inverse = options.inverse,
    ret = "",
    _context = [];
    $.each(context, function (index, object) {
        var _object = $.extend({}, object);
        _context.push(_object);
    });
if ( _context && _context.length > 0 ) {
    for ( var i = 0, j = _context.length; i < j; i++ ) {
        _context[i]["parentContext"] = options.hash.parent;
        ret = ret + fn(_context[i]);
    }
} else {
    ret = inverse(this);
}
return ret;

});

使用方法如下:

{{#eachIncludeParent context parent=this}}
    {{> yourPartial}}
{{/eachIncludeParent}}

使用{{parentContext.value}}

访问部分中的父上下文值

答案 6 :(得分:0)

我需要这样的动态表单属性......

    {{#each model.questions}}
      <h3>{{text}}</h3>

          {{#each answers}}
                {{formbuilder ../type id ../id text}}
            {{/each}}

    {{/each}}

和这样的帮手......

    Handlebars.registerHelper('formbuilder', function(type, id, qnum, text, options)
    {
        var q_type = options.contexts[0][type],
            a_id = options.contexts[1].id,
            q_number = options.contexts[0][qnum],
            a_text = options.contexts[1].text;


            return new Handlebars.SafeString(
                    '<input type=' + q_type + ' id=' + a_id + ' name=' + q_number + '>' + a_text + '</input><br/>'
            );
    });

哪个产生......

<input type="checkbox" id="1" name="surveyQ0">First question</input>

我的模型是一大堆数组和对象混合在一起。值得注意的是,使用'../'就像'../type'一样,将父模型作为上下文传递,没有它,例如使用'id',它会将当前模型作为上下文传递。< / p>

答案 7 :(得分:-1)

要明确获取部分的父级(您可能在其中有多个部分深),请遵循诸如SeanWM之类的其他答案。

如果您知道父级是主要模板,那么无论您有多深,都可以使用@root解析到最顶层的上下文。

例如{{@ root.rootObject.rootProperty}}

可惜../../ ..没有超过部分。