handlebars - is it possible to access parent context in a partial?

℡╲_俬逩灬. 提交于 2019-11-28 03:53:38

Just in case anyone stumbles across this question. This functionality exists now in Handlebars.

Do this:

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

Working fiddle (inspired by handlebars pull request #385 by AndrewHenderson) 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);
});

Here's how you'd setup the parent template:

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

And the partial:

value is {{parent}}

As of 2.0.0 partials now supports passing in values.

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

Took me awhile to find this, hope it's useful for someone else too!

The easiest way to pass the parent context to the partial is to do the loop inside the partial. This way the parent context is passed by default and when you do the loop inside the partial the {{../variable}} convention can access the parent context.

example fiddle here.

The Data

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

The Template

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

The Partial

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

You can use some of the proposed solutions on the comments from the link to github:

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

They create helpers to pass the info to the partial.

I created an each Helper function that includes the parent key/values within the subcontext under the key parentContext.

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

Note: Underscore is a dependency.

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;

});

To be used as follows:

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

Access parent context values in your partial using {{parentContext.value}}

I needed dynamic form attributes for something like this...

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

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

    {{/each}}

and a helper like so...

    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/>'
            );
    });

Which produces...

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

My model is a big blob of arrays and objects mixed together. What's noteworthy is that using '../' like so '../type', passes in the parent model as the context, and without it, such as with 'id', it passes in the current model as the context.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!