Meteor(with Handlebars)のテンプレートのイベントハンドラーのコンテキストに関する簡単な質問。
まあ、これは部分的に真実です。ドキュメントの例を使用してみましょう。
<template name="scores">
{{#each player}}
{{> playerScore}}
{{/each}}
</template>
<template name="playerScore">
<div>{{name}}: {{score}}
<span class="givePoints">Give points</span>
</div>
</template
Template.playerScore.events({
'click .givePoints': function () {
Users.update({_id: this._id}, {$inc: {score: 2}});
});
ここで、「click .givePoints」イベントハンドラの「this」コンテキストは、実際にはplayerScoreのテンプレートインスタンスです。 htmlを変更しましょう:
<template name="scores">
<span class="click-me">Y U NO click me?<span>
{{#each player}}
{{> playerScore}}
{{/each}}
</template>
<template name="playerScore">
<div>{{name}}: {{score}}
<span class="givePoints">Give points</span>
</div>
</template>
...スコアテンプレートに.click-meのイベントハンドラーを追加します。
Template.scores.events({
'click .click-me': function () {
console.log(this);
}
});
スパンをクリックすると、何が記録されますか? Windowオブジェクト!何を期待していましたか?テンプレートオブジェクト!または、データコンテキストかもしれませんが、どちらでもありません。ただし、コールバック(例:Template.scores.rendered = function(){...})内では、「this」のコンテキストは常にテンプレートインスタンスです。
私の本当の質問は次のようになると思います:これは何か
ありがとう!
このビデオでは、概念について説明します。
http://www.eventedmind.com/posts/meteor-spark-data-annotation-and-data-contexts 。
あなたの質問への直接的な答え:
イベントハンドラー内のthisArgshouldはデータコンテキストを指します。ただし、データコンテキストがundefined
である場合があります。 JavaScriptでFunction.prototype.call(thisArg, ...)
を使用する場合、thisArgが未定義(たとえば、dataContextが未定義)の場合、ブラウザはthis
をwindowと等しく設定します。したがって、ドキュメント自体はwrongではありませんが、イベント処理コードは、データコンテキストが未定義になる可能性を保護していません。私はそれがすぐに修正されると推測しています。
では、何がテンプレートのデータコンテキストを生成しますか?通常、ルートテンプレートにはデータコンテキストさえありません。つまり、テンプレート関数はオブジェクトなしで呼び出されます。ただし、{{#with
ブロックヘルパーまたは{{#each
イテレータ、リスト内の各アイテム、またはwithヘルパーの場合はオブジェクトのデータコンテキストが作成されます。
例:
var context = {};
<template name="withHelper">
{{#with context}}
// data context is the context object
{{/with}}
</template>
var list = [ {name: "one"}, {name: "two"} ];
<template name="list">
{{#each list}}
{{ > listItem }} // data context set to the list item object
{{/each}}
</template>
関数の最初のパラメーターはイベントです。そのため、イベントのターゲットを使用して要素を取得できます。
Template.scores.events({
'click .click-me': function (event, template) {
console.log(event.target);
$(event.target).text("O but I did!");
}
});