通过句柄部分传递变量

我目前正在一个 Express.js 应用程序中处理 handlebars.js。

我的问题 : 我无法找到通过部分调用传递变量的方法。假设我有一部分是这样的:

<div id=myPartial>
<h1>Headline<h1>
<p>Lorem ipsum</p>
</div>

让我们假设我注册了这个片段的名称为“ myPartial”,然后在另一个模板中我可以这样说:

<section>
{{> myPartial}}
</section>

这个工作很好,部分将按预期呈现,我是一个快乐的开发人员。但是我现在需要的是,一种通过这个调用传递不同变量的方法,例如,在一个片段中检查,是否给出了标题。比如:

<div id=myPartial>
{{#if headline}}
<h1>{{headline}}</h1>
{{/if}}
<p>Lorem Ipsum</p>
</div>

调用应该是这样的:

<section>
{{> myPartial|'headline':'Headline'}}
</section>

差不多吧。

我知道,在我呈现模板之前,我能够定义我需要的所有数据。但我需要一个方法来做到这一点,就像刚才解释的那样。有可能吗?

166311 次浏览

句柄部分接受第二个参数,该参数将成为部分的上下文:

\{\{> person this}}

在版本2.0.0 alpha 和更高版本中,还可以传递命名参数的散列:

\{\{> person headline='Headline'}}

您可以看到这些场景的测试: < a href = “ https://github.com/wyats/handlebars.js/blob/ce74c36118ffed177989d97e6a2a1028ae61510/spec/qunit _ spec.js # L456-L462”rel = “ norefrer”> https://github.com/wycats/handlebars.js/blob/ce74c36118ffed1779889d97e6a2a1028ae61510/spec/qunit_spec.js#l456-l462 Https://github.com/wycats/handlebars.js/blob/e290ec24f131f89ddf2c6aeb707a4884d41c3c6d/spec/partials.js#l26-l32

如果您编写自己的助手,这是非常可能的。我们使用一个定制的 $助手来完成这种类型的交互(以及更多) :

/*///////////////////////


Adds support for passing arguments to partials. Arguments are merged with
the context for rendering only (non destructive). Use `:token` syntax to
replace parts of the template path. Tokens are replace in order.


USAGE: \{\{$ 'path.to.partial' context=newContext foo='bar' }}
USAGE: \{\{$ 'path.:1.:2' replaceOne replaceTwo foo='bar' }}


///////////////////////////////*/


Handlebars.registerHelper('$', function(partial) {
var values, opts, done, value, context;
if (!partial) {
console.error('No partial name given.');
}
values = Array.prototype.slice.call(arguments, 1);
opts = values.pop();
while (!done) {
value = values.pop();
if (value) {
partial = partial.replace(/:[^\.]+/, value);
}
else {
done = true;
}
}
partial = Handlebars.partials[partial];
if (!partial) {
return '';
}
context = _.extend({}, opts.context||this, _.omit(opts, 'context', 'fn', 'inverse'));
return new Handlebars.SafeString( partial(context) );
});

以防万一,这是我得到的部分参数。我已经创建了一个小帮助程序,它接受将传递给该部分的部分名称和参数散列:

Handlebars.registerHelper('render', function(partialId, options) {
var selector = 'script[type="text/x-handlebars-template"]#' + partialId,
source = $(selector).html(),
html = Handlebars.compile(source)(options.hash);


return new Handlebars.SafeString(html);
});

关键是 句柄助手接受类似 Ruby 的散列参数。在 helper 代码中,它们作为函数的最后一个参数ーー optionsーー的 hash成员的一部分。通过这种方式,您可以接收第一个参数ーー部分名称ーー并在此之后获取数据。

然后,您可能希望从助手返回一个 Handlebars.SafeString,或者使用“ three-stash”ー \{\{{ー来防止它重复转义。

下面是一个或多或少完整的使用场景:

<script id="text-field" type="text/x-handlebars-template">
<label for="\{\{id}}">\{\{label}}</label>
<input type="text" id="\{\{id}}"/>
</script>


<script id="checkbox-field" type="text/x-handlebars-template">
<label for="\{\{id}}">\{\{label}}</label>
<input type="checkbox" id="\{\{id}}"/>
</script>


<script id="form-template" type="text/x-handlebars-template">
<form>
<h1>\{\{title}}</h1>
\{\{ render 'text-field' label="First name" id="author-first-name" }}
\{\{ render 'text-field' label="Last name" id="author-last-name" }}
\{\{ render 'text-field' label="Email" id="author-email" }}
\{\{ render 'checkbox-field' label="Private?" id="private-question" }}
</form>
</script>

希望这对某人有所帮助

这也可以在以后版本的车把上使用 key=value表示法:

 \{\{> mypartial foo='bar' }}

允许您向部分上下文传递特定值。

参考资料: 部分 # 182的上下文不同

是的,我迟到了,但是我可以为 集合用户添加: 您可以使用内置的 "parseJSON"助手 http://assemble.io/helpers/helpers-data.html。(发现于 https://github.com/assemble/assemble/issues/416)。

听起来你想做这样的事:

\{\{> person {another: 'attribute'} }}

耶胡达已经给了你一个方法:

\{\{> person this}}

但需要澄清的是:

要给部分数据提供它自己的数据,只需在现有模型中给它自己的模型,如下所示:

\{\{> person this.childContext}}

换句话说,如果这是你给你的模板的模型:

var model = {
some : 'attribute'
}

然后添加一个新的对象给这个片段:

var model = {
some : 'attribute',
childContext : {
'another' : 'attribute' // this goes to the child partial
}
}

就像 Yehuda 说的那样,childContext成为了片段的上下文——在这种情况下,它只能看到字段 another,但是不能看到(或者关心字段 some)。如果您在顶级模型中使用 id,并在 child Context 中再次重复 id,那么这样就可以了,因为部分只能看到 childContext中的内容。

如果您只是想在部分中使用不同的上下文,那么接受的答案非常有用。但是,它不允许您引用任何父上下文。要传入多个参数,需要编写自己的助手。下面是 Handlebar 2.0.0的工作助手(另一个答案适用于版本 <2.0.0) :

Handlebars.registerHelper('renderPartial', function(partialName, options) {
if (!partialName) {
console.error('No partial name given.');
return '';
}
var partial = Handlebars.partials[partialName];
if (!partial) {
console.error('Couldnt find the compiled partial: ' + partialName);
return '';
}
return new Handlebars.SafeString( partial(options.hash) );
});

然后在你的模板中,你可以这样做:

\{\{renderPartial 'myPartialName' foo=this bar=../bar}}

在您的部分中,您可以根据上下文访问这些值,比如:

<div id=\{\{bar.id}}>\{\{foo}}</div>

不确定这是否有帮助,但是这里有一个 Handlebar 模板的示例,其中动态参数传递给内联 RadioButtons 部分和客户端(浏览器)在容器中呈现单选按钮。

对于我的使用,它是在服务器上用 Handlebar 呈现的,并让客户端完成它。 通过它,表单工具可以在 Handlebar 中提供内联数据,而不需要辅助工具。

注意: 这个例子需要 jQuery

\{\{#*inline "RadioButtons"}}
\{\{name}} Buttons<hr>
<div id="key-\{\{{name}}}"></div>
<script>
\{\{{buttons}}}.map((o)=>{
$("#key-\{\{name}}").append($(''
+'<button class="checkbox">'
+'<input name="\{\{{name}}}" type="radio" value="'+o.value+'" />'+o.text
+'</button>'
));
});
// A little test script
$("#key-\{\{{name}}} .checkbox").on("click",function(){
alert($("input",this).val());
});
</script>
\{\{/inline}}
\{\{>RadioButtons name="Radio" buttons='[
{value:1,text:"One"},
{value:2,text:"Two"},
{value:3,text:"Three"}]'
}}