Javascript 通过把手部分传递变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11523331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing variables through handlebars partial
提问by Pascal Precht
I'm currently dealing with handlebars.js in an express.js application. To keep things modular, I split all my templates in partials.
我目前正在处理 express.js 应用程序中的 handlebars.js。为了保持模块化,我将所有模板拆分为部分。
My problem: I couldn't find a way to pass variables through an partial invocation. Let's say I have a partial which looks like this:
我的问题:我找不到通过部分调用传递变量的方法。假设我有一个看起来像这样的部分:
<div id=myPartial>
<h1>Headline<h1>
<p>Lorem ipsum</p>
</div>
Let's assume I registered this partial with the name 'myPartial'. In another template I can then say something like:
假设我使用名称“myPartial”注册了这个部分。在另一个模板中,我可以这样说:
<section>
{{> myPartial}}
</section>
This works fine, the partial will be rendered as expected and I'm a happy developer. But what I now need, is a way to pass different variables throught this invocation, to check within a partial for example, if a headline is given or not. Something like:
这工作正常,部分将按预期呈现,我是一个快乐的开发人员。但是我现在需要的是一种通过此调用传递不同变量的方法,例如检查部分是否给出了标题。就像是:
<div id=myPartial>
{{#if headline}}
<h1>{{headline}}</h1>
{{/if}}
<p>Lorem Ipsum</p>
</div>
And the invokation should look something like this:
调用应该是这样的:
<section>
{{> myPartial|'headline':'Headline'}}
</section>
or so.
或者。
I know, that I'm able to define all the data I need, before I render a template. But I need a way to do it like just explained. Is there a possible way?
我知道,在渲染模板之前,我能够定义我需要的所有数据。但我需要一种方法来做到这一点,就像刚才解释的那样。有没有可能的方法?
回答by Yehuda Katz
Handlebars partials take a second parameter which becomes the context for the partial:
Handlebars 部分采用第二个参数,该参数成为部分的上下文:
{{> person this}}
In versions v2.0.0 alpha and later, you can also pass a hash of named parameters:
在 v2.0.0 alpha 及更高版本中,您还可以传递命名参数的散列:
{{> person headline='Headline'}}
You can see the tests for these scenarios: https://github.com/wycats/handlebars.js/blob/ce74c36118ffed1779889d97e6a2a1028ae61510/spec/qunit_spec.js#L456-L462https://github.com/wycats/handlebars.js/blob/e290ec24f131f89ddf2c6aeb707a4884d41c3c6d/spec/partials.js#L26-L32
您可以查看这些场景的测试:https: //github.com/wycats/handlebars.js/blob/ce74c36118ffed1779889d97e6a2a1028ae61510/spec/qunit_spec.js#L456-L462 https://github.com/wycats/handle blob/e290ec24f131f89ddf2c6aeb707a4884d41c3c6d/spec/partials.js#L26-L32
回答by Vlad GURDIGA
Just in case, here is what I did to get partial arguments, kind of. I've created a little helper that takes a partial name and a hash of parameters that will be passed to the partial:
以防万一,这是我为获得部分参数所做的工作,有点。我创建了一个小助手,它采用部分名称和将传递给部分的参数散列:
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);
});
The key thing here is that Handlebars helpers accept a Ruby-like hash of arguments. In the helper code they come as part of the function's last argument—options
— in its hash
member. This way you can receive the first argument—the partial name—and get the data after that.
这里的关键是Handlebars 助手接受类似 Ruby 的参数散列。在帮助器代码中,它们作为函数最后一个参数的一部分出现options
——在它的hash
成员中。这样你就可以接收第一个参数——部分名称——然后获取数据。
Then, you probably want to return a Handlebars.SafeString
from the helper or use “triple?stash”—{{{
— to prevent it from double escaping.
然后,您可能希望Handlebars.SafeString
从帮助程序返回 a或使用“triple?stash”— {{{
— 以防止其双重转义。
Here is a more or less complete usage scenario:
这是一个或多或少完整的使用场景:
<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>
Hope this helps …someone. :)
希望这有助于......某人。:)
回答by Jesse Houchins
This is very possible if you write your own helper. We are using a custom $
helper to accomplish this type of interaction (and more):
如果您编写自己的助手,这是很有可能的。我们正在使用自定义$
助手来完成这种类型的交互(以及更多):
/*///////////////////////
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) );
});
回答by cweston
This can also be done in later versions of handlebars using the key=value
notation:
这也可以使用key=value
符号在更高版本的车把中完成:
{{> mypartial foo='bar' }}
Allowing you to pass specific values to your partial context.
允许您将特定值传递给部分上下文。
Reference: Context different for partial #182
回答by Andrew C
The accepted answer works great if you just want to use a different context in your partial. However, it doesn't let you reference any of the parent context. To pass in multiple arguments, you need to write your own helper. Here's a working helper for Handlebars 2.0.0
(the other answer works for versions <2.0.0
):
如果您只想在部分内容中使用不同的上下文,那么接受的答案效果很好。但是,它不允许您引用任何父上下文。要传入多个参数,您需要编写自己的助手。这是 Handlebars 的工作助手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) );
});
Then in your template, you can do something like:
然后在您的模板中,您可以执行以下操作:
{{renderPartial 'myPartialName' foo=this bar=../bar}}
And in your partial, you'll be able to access those values as context like:
在您的部分中,您将能够访问这些值作为上下文,例如:
<div id={{bar.id}}>{{foo}}</div>
回答by Chunky Bacon
Sounds like you want to do something like this:
听起来你想做这样的事情:
{{> person {another: 'attribute'} }}
Yehuda already gave you a way of doing that:
Yehuda 已经为您提供了一种方法:
{{> person this}}
But to clarify:
但要澄清:
To give your partial its own data, just give it its own model inside the existing model, like so:
要为您的部分提供自己的数据,只需在现有模型中为其提供自己的模型,如下所示:
{{> person this.childContext}}
In other words, if this is the model you're giving to your template:
换句话说,如果这是您为模板提供的模型:
var model = {
some : 'attribute'
}
Then add a new object to be given to the partial:
然后添加一个新对象以赋予部分:
var model = {
some : 'attribute',
childContext : {
'another' : 'attribute' // this goes to the child partial
}
}
childContext
becomes the context of the partial like Yehuda said -- in that, it only sees the field another
, but it doesn't see (or care about the field some
). If you had id
in the top level model, and repeat id
again in the childContext, that'll work just fine as the partial only sees what's inside childContext
.
childContext
变成了像 Yehuda 所说的部分的上下文——在那种情况下,它只看到领域another
,但它没有看到(或关心领域some
)。如果您id
在顶级模型中,并id
在 childContext 中再次重复,那将工作得很好,因为部分只看到里面的内容childContext
。
回答by vasiliy0s
Yes, I was late, but I can add for Assembleusers: you can use buil-in "parseJSON"
helper http://assemble.io/helpers/helpers-data.html. (Discovered in https://github.com/assemble/assemble/issues/416).
是的,我迟到了,但我可以为Assemble用户添加:您可以使用内置"parseJSON"
帮助程序http://assemble.io/helpers/helpers-data.html。(在https://github.com/assemble/assemble/issues/416 中发现)。
回答by Richard Taylor-Kenny
Not sure if this is helpful but here's an example of Handlebars template with dynamic parameters passed to an inline RadioButtons partial and the client(browser) rendering the radio buttons in the container.
不确定这是否有帮助,但这里有一个 Handlebars 模板示例,其中动态参数传递给内联 RadioButtons 部分和客户端(浏览器)呈现容器中的单选按钮。
For my use it's rendered with Handlebars on the server and lets the client finish it up. With it a forms tool can provide inline data within Handlebars without helpers.
对于我的使用,它在服务器上使用 Handlebars 呈现并让客户端完成它。有了它,表单工具可以在 Handlebars 中提供内联数据,而无需帮助。
Note : This example requires jQuery
注意:此示例需要 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"}]'
}}