2012-02-23 2 views
57

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

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

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

шаблон

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

Есть ли способ, чтобы обойти этот вопрос? Я что-то упускаю?

EDIT: Там же открытый вопрос, касающийся этого вопроса на handlebars' github project

ответ

3

Вы можете использовать некоторые из предложенных решений замечаний, полученных от ссылки на GitHub:

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

Они создают помощников, чтобы передать информацию частичным.

+0

хорошо, очевидно .. – Ben

+0

Да! Иногда мы пропускаем очевидный поиск других решений. По крайней мере, пока они не выпустят веху или новую версию. – rcdmk

+0

Это просто невероятно неподходящее решение – Marc

2

Я создал каждую функцию Помощника, которая включает родительский ключ/значения в подконтексте под ключ 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}}

+0

Как это исправить проблему? Кроме того, существует опция 'var option =', которая, как представляется, не используется впоследствии. – Ben

+0

Если вы используете этот помощник, у вас будет доступ к одному объекту в частичном шаблоне, который содержит все значения, как родительский, так и дочерний объект. Это в основном объединенный контекст. – AndrewHenderson

+0

Примечание: дочерние и родительские значения будут на том же уровне в этой точке. – AndrewHenderson

36

Только в случае, если кто-нибудь натыкается этот вопрос. Эта функциональность существует теперь в Handlebars.

ли это:

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

Спасибо @ james-andres. Хорошо знать, что это наконец. Я дам ему спину, чтобы подтвердить .. – Ben

+0

Это должно быть отмечено как принятый ответ. – lbergnehr

+14

Просто проверил это. Доенст работает для меня, к сожалению. Родительский контекст не проходит. «this» относится только к элементам [: index], поэтому родительский контекст не учитывается. И если вы передадите «..», который будет включать родительский контекст, вы не сможете получить доступ к текущему элементу в частичном. – Hans

21

Работа скрипку (вдохновленный рули тянуть запрос # 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

Я предпочел этот подход для его чистоты и гибкости по сравнению с остальными – mynameistechno

+1

в рулях 2.0, эта функциональность [будет включена] (https://github.com/wycats/handlebars.js/pull/182) – Jason

+0

Это замечательно. Имейте в виду, что если вы передадите частичное частичное, вам нужно будет ссылаться на родителя следующим образом: '{{parent.parent.id}}' –

3

Самый простой способ передать родительский контекст частичным - это сделать цикл внутри частичного. Таким образом, родительский контекст передается по умолчанию, и когда вы выполняете цикл внутри частичного, соглашение {{../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> 
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», она передает текущую модель в качестве контекста.

+0

Это не имеет особого отношения к вопросу .. – Ben

7

От 2.0.0partials now supports passing in values.

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

Пришло время найти это, надеясь, что это тоже полезно для кого-то еще!

Смежные вопросы