2012-02-23 25 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}} 

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

编辑:有关于这个问题的公开问题上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 2012-06-11 23:00:02

+0

是啊!有时我们会错过显而易见的其他解决方案。至少,直到他们发布里程碑或新版本。 – rcdmk 2012-06-12 12:44:26

+0

这只是一个令人难以置信的不雅的解决方案 – Marc 2012-08-02 14:32:47

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; 

});使用{{parentContext.value}}

+0

这是如何解决问题的?另外,还有一个'var option =',似乎​​以后不会使用.. – Ben 2012-12-04 02:38:36

+0

如果您使用此帮助程序,您将有权访问包含所有值的部分模板中的一个对象,包括父项和子对象。这基本上是一个合并的上下文。 – AndrewHenderson 2012-12-06 00:58:04

+0

注意:此时孩子和父母的值将处于相同的水平。 – AndrewHenderson 2012-12-06 01:00:40

36

万一有人碰到这个问题绊倒在部分

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

访问父上下文值:

要如下使用。此功能现在在Handlebars中存在。

这样做:

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

谢谢@ james-andres。很高兴知道这是终于在。我会给它一个旋转确认.. – Ben 2013-02-04 11:06:00

+0

这应该被标记为接受的答案。 – lbergnehr 2013-03-16 19:05:46

+14

刚刚测试过。 Doenst不幸地为我工作。父上下文不通过。 “this”仅引用项目[:index],因此父上下文被省略。如果你传递“..”,这将包括父上下文,你不能访问部分当前项目。 – Hans 2013-06-28 15:12:04

21

工作小提琴(由车把启发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}} 
+3

我优选这种方法进行其清洁和灵活性相对于其他 – mynameistechno 2014-01-17 23:10:17

+1

在车把2.0,该功能[将包含](https://github.com/wycats/handlebars.js/pull/182) – Jason 2014-04-21 21:45:38

+0

这是巨大的。请记住,如果你传递一个partial到partial,你需要像这样引用父项:'{{parent.parent.id}}' – 2014-08-21 15:43:58

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

我需要动态˚F ORM属性这样的事情...

{{#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 2014-04-06 06:28:59

相关问题