テンプレートコンテキストの状況に陥り、その方法を見つけるのに苦労しています。
問題のテンプレートは次のとおりです
{{#each votes}}
<h3>{{question}}</h3>
<ul>
{{#each participants}}
<li>
<p>{{email}}</p>
<select name="option-select">
{{#each ../options}}
<option value="{{option}}" class="{{is_selected_option}}">{{option}}</option>
{{/each}}
</select>
</li>
{{/each}}
</ul>
</div>
{{/each}}
そして、ここに投票文書の例があります:
{
_id: '32093ufsdj90j234',
question: 'What is the best food of all time?'
options: [
'Pizza',
'Tacos',
'Salad',
'Thai'
],
participants: [
{
id: '2f537a74-3ce0-47b3-80fc-97a4189b2c15'
vote: 0
},
{
id: '8bffafa7-8736-4c4b-968e-82900b82c266'
vote: 1
}
]
}
そして、ここに問題があります...
テンプレートが参加者の#each
にドロップすると、vote
コンテキストにアクセスできなくなるため、各投票で使用可能なオプションにアクセスできなくなります。
私はやや../options
handlebarsパスを使用して親コンテキストに戻ることでこれを回避できますが、これはコンテキストに影響しませんテンプレートヘルパーのthis
in Template.vote.is_selected_option
は、現在のparticipant
またはvote
ではなく、現在のoption
を参照し、現在どのoption
を反復処理しているかを知る方法。
DOM操作やjQueryに頼らずにこれを回避する方法についての提案はありますか?
これはテンプレートの問題で、私にとっては何度も出てきました。テンプレート、テンプレートヘルパー、およびテンプレートイベントで、テンプレートコンテキスト階層に到達する正式な方法が必要です。
特にきれいではありませんが、私はこのようなことをしました:
<template name='forLoop'>
{{#each augmentedParticipants}}
{{> participant }}
{{/each}}
</template>
<template name='participant'>
...
Question: {{this.parent.question}}
...
</template>
// and in the js:
Template.forLoop.helpers({
augmentedParticipants: function() {
var self = this;
return _.map(self.participants,function(p) {
p.parent = self;
return p;
});
}
});
これはAVGPが提案したアプローチに似ていますが、dbレベルではなくヘルパーレベルでデータを拡張します。
気に入れば、この機能を抽象化するHandlebarsブロックヘルパーeachWithParent
を記述してみてください。 Meteorのハンドルバーへの拡張機能はここに文書化されています: https://github.com/meteor/meteor/wiki/Handlebars
スペースバー(流星の新しいテンプレートエンジン) なので、_{{#each}}
_を使用して_../
_ブロック内の親コンテキストにアクセスできます。
Meteor 0.9.1では、ヘルパーを記述し、その実装で Template.parentData()
を使用することもできます。
これにより、生活が楽になります。
// use #eachWithParent instead of #each and the parent._id will be passed into the context as parent.
Handlebars.registerHelper('eachWithParent', function(context, options) {
var self = this;
var contextWithParent = _.map(context,function(p) {
p.parent = self._id;
return p;
});
var ret = "";
for(var i=0, j=contextWithParent.length; i<j; i++) {
ret = ret + options.fn( contextWithParent[i] );
}
return ret;
});
先に行くと変更
p.parent = self._id;
親コンテキストでアクセスしたいものに。
修正済み:
// https://github.com/meteor/handlebars.js/blob/master/lib/handlebars/base.js
// use #eachWithParent instead of #each and the parent._id will be passed into the context as parent.
Handlebars.registerHelper('eachWithParent', function(context, options) {
var self = this;
var contextWithParent = _.map(context,function(p) {
p.parent = self._id;
return p;
});
return Handlebars._default_helpers.each(contextWithParent, options);
});
これは動作します:)エラーなし
それは長いショットですが、おそらくこれはうまくいくかもしれません:
{{#with ../}}
{{#each options}}
{{this}}
{{/each}}
{{/with}}
グローバルテンプレートヘルパーを登録するだけです:
Template.registerHelper('parentData',
function () {
return Template.parentData(1);
}
);
hTMLテンプレートで次のように使用します。
{{#each someRecords}}
{{parentData.someValue}}
{{/each}}
=======編集
Meteor 1.2+の場合、以下を使用する必要があります。
UI.registerHelper('parentData', function() {
return Template.parentData(1);
});
正式な方法(ある場合)はわかりませんが、問題を解決するために、次のように参加者を親IDにリンクします。
{
_id: "1234",
question: "Whats up?",
...
participants: [
{
_id: "abcd",
parent_id: "1234",
vote: 0
}
]
}
そして、このparent_idをヘルパー、イベントなどで使用して、findOneを使用して親に戻ります。これは明らかに最適ではありませんが、親コンテキストを参照する方法がない限り、最も簡単な方法です。方法はあるかもしれませんが、ドキュメントに記載されていない場合は、Meteorの内部の動作に非常によく隠されています。
私は同様の方法で立ち往生し、他の回答で提案されているTemplate.parentData()アプローチが現在イベントハンドラー内で機能しないことがわかりました( https://github.com/meteor/meteor/issues/5491を参照) )。ユーザーLirbankは、この簡単な回避策を投稿しました。
同じテンプレートで、外側のコンテキストから内側のコンテキストのhtml要素にデータを渡します。
{{#each companies}}
{{#each employees}}
<a href="" companyId="{{../id}}">Do something</a>
{{/each}}
{{/each}}
これで、次のようなイベントハンドラーから会社IDにアクセスできます。
$(event.currentTarget).attr('companyId')
"click .selected":function(e){
var parent_id = $(e.currentTarget).parent().attr("uid");
return parent_id
},
<td id="" class="staff_docs" uid="{{_id}}">
{{#each all_req_doc}}
<div class="icheckbox selected "></div>
{{/each}}
</td>
{{#each parent}}
{{#each child}}
<input type="hidden" name="child_id" value="{{_id}}" />
<input type="hidden" name="parent_id" value="{{../_id}}" />
{{/each}}
{{/each}}
_idは事の_didではなく、親のidです!