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,
Ответы
Ответ 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}}
Ответ 3
По состоянию на 2.0.0 частичные теперь поддерживают передачу значений. p >
{{#each items}}
{{> item-template some_parent_var=../some_parent_var}}
{{/each}}
Пришло время найти это, надеюсь, это полезно и для кого-то другого!
Ответ 4
Вы можете использовать некоторые из предлагаемых решений по комментариям ссылки на github:
https://github.com/wycats/handlebars.js/issues/182#issuecomment-4206666
https://github.com/wycats/handlebars.js/issues/182#issuecomment-4445747
Они создают помощников для передачи информации частичным.
Ответ 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", она передает текущую модель в качестве контекста.