Подтвердить что ты не робот

Handlebars - возможно ли получить доступ к родительскому контексту в частичном?

У меня есть шаблон дескриптора, который загружает частичный элемент для подэлемента.

Мне нужно будет получить доступ к переменной из родительского контекста в вызывающем шаблоне, из частичного. .., похоже, не разрешает ничего внутри частичного.

Упрощенный код выглядит следующим образом:

шаблон

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

частичный

    value is {{value}}

(очевидно, что реальный код более сложный, но тот же самый принцип в частичном .. выглядит как undefined.)


Чтобы показать его undefined, я использовал очень простой помощник 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}}

Есть ли способ обойти эту проблему? Я что-то пропустил?

РЕДАКТИРОВАТЬ: Открытая проблема, связанная с этим вопросом в проекте github gbubb,

4b9b3361

Ответ 1

На всякий случай кто-то споткнется по этому вопросу. Эта функциональность существует теперь в Handlebars.

Сделайте это:

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

Ответ 2

Рабочая скрипка (вдохновленная запросом на тягу руля # 385 от 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);
});

Здесь вы можете настроить родительский шаблон:

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

И частичное:

value is {{parent}}

Ответ 5

Самый простой способ передать родительский контекст частичным - это сделать цикл внутри частичного. Таким образом, родительский контекст передается по умолчанию, и когда вы выполняете цикл внутри частичного, соглашение {{../variable}} может обращаться к родительскому контексту.

пример скрипки здесь.

Данные

{
  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>

Ответ 6

Я создал каждую функцию Helper, которая включает родительский ключ/значения в подконтексте под ключевым родительским контекстом.

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}}

Ответ 7

Мне нужны динамические атрибуты формы для чего-то вроде этого...

    {{#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", она передает текущую модель в качестве контекста.