現在、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>
とか、ぐらい。
テンプレートをレンダリングする前に、必要なすべてのデータを定義できることを知っています。しかし、今説明したような方法が必要です。可能な方法はありますか?
ハンドルバーのパーシャルは、パーシャルのコンテキストになる2番目のパラメーターを取ります。
{{> person this}}
バージョンv2.0.0アルファ以降では、名前付きパラメーターのハッシュを渡すこともできます。
{{> person headline='Headline'}}
これらのシナリオのテストを見ることができます: 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
念のため、部分的な引数を取得するために私がやったことがあります。パーシャル名と、パーシャルに渡されるパラメーターのハッシュを受け取る小さなヘルパーを作成しました。
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のような引数のハッシュを受け入れる です。ヘルパーコードでは、options
メンバーの関数の最後の引数、hash
の一部として提供されます。この方法では、最初の引数(部分名)を受け取り、その後でデータを取得できます。
次に、ヘルパーからHandlebars.SafeString
を返すか、「トリプルスタッシュ」—{{{
—を使用して、ダブルエスケープを防ぎます。
以下は、多かれ少なかれ完全な使用シナリオです。
<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>
これが誰かに役立つことを願っています。 :)
独自のヘルパーを作成する場合、これは非常に可能です。このタイプの対話(およびその他)を実現するために、カスタム$
ヘルパーを使用しています。
/*///////////////////////
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) );
});
これは、key=value
表記を使用して、後のバージョンのハンドルバーでも実行できます。
{{> mypartial foo='bar' }}
部分的なコンテキストに特定の値を渡すことができます。
パーシャルで別のコンテキストを使用したいだけの場合、受け入れられた答えは素晴らしいです。ただし、親コンテキストを参照することはできません。複数の引数を渡すには、独自のヘルパーを作成する必要があります。これが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) );
});
次に、テンプレートで次のようなことができます。
{{renderPartial 'myPartialName' foo=this bar=../bar}}
パーシャルでは、次のようなコンテキストとしてこれらの値にアクセスできます。
<div id={{bar.id}}>{{foo}}</div>
次のようなことをしたいようです。
{{> 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
}
}
childContext
は、Yehudaが言ったようにパーシャルのコンテキストになります。つまり、フィールドanother
のみが表示されますが、表示されません(またはフィールドsome
が重要です)。最上位モデルにid
があり、childContextでid
を再度繰り返した場合、パーシャルはchildContext
の中にあるものだけを見るため、それはうまく機能します。
はい、遅れましたが、Assembleユーザーに追加できます。buil-in"parseJSON"
ヘルパーを使用できます http:// assemble。 io/helpers/helpers-data.html 。 ( https://github.com/assemble/assemble/issues/416 で発見)。
これが役立つかどうかはわかりませんが、インラインRadioButtonsパーシャルに渡される動的パラメーターと、コンテナー内のラジオボタンをレンダリングするクライアント(ブラウザー)を持つHandlebarsテンプレートの例を次に示します。
私の使用のために、サーバー上のHandlebarsでレンダリングされ、クライアントがそれを仕上げることができます。これにより、フォームツールはヘルパーなしでHandlebars内にインラインデータを提供できます。
注:この例には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"}]'
}}