42

Meteor (ハンドルバー付き) のテンプレートのイベント ハンドラーのコンテキストに関する簡単な質問です。

  • テンプレート インスタンスに関するドキュメントのセクション ( http://docs.meteor.com/#template_inst ) では、「テンプレート インスタンス オブジェクトは、作成、レンダリング、および破棄されたテンプレート コールバック内の this の値として、およびイベントハンドラへの引数"
  • テンプレート セクション ( http://docs.meteor.com/#templates ) には、「最後に、テンプレート関数でイベント宣言を使用して、イベント ハンドラーのテーブルを設定できます。形式は Event Maps に記載されています。イベント ハンドラーへの this 引数は、イベントをトリガーした要素のデータ コンテキストになります。 "

まあ、これは部分的にしか当てはまりません。ドキュメントの例を使用しましょう。

<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);
  }
});

では、スパンをクリックすると、何がログに記録されるでしょうか? ウィンドウオブジェクト!私は何を得ることを期待していましたか?テンプレートオブジェクト!または、データ コンテキストかもしれませんが、どちらでもありません。ただし、コールバック (例: Template.scores.rendered = function(){ ... }) 内では、"this" のコンテキストは常にテンプレート インスタンスです。

私の本当の質問は次のようになると思います:これは何か関係がありますか

  • ハンドルバー、Meteor、またはその間のどこかにバグがありますか?
  • テンプレートに関するわずかに不完全なドキュメント?
  • ドキュメントを完全に誤解していたり​​、Meteor やハンドルバーに関する基本的なことを理解していませんか?

ありがとう!

4

2 に答える 2

27

このビデオでは、概念について説明しています。

http://www.eventedmind.com/posts/meteor-spark-data-annotation-and-data-contexts

あなたの質問への直接の答え:

イベントハンドラー内のthisArgは、データコンテキストを指している必要がありますただし、データコンテキストがである場合もありますundefined。JavaScriptでinを使用するFunction.prototype.call(thisArg, ...)場合、thisArgが未定義の場合(たとえば、dataContextが未定義の場合)、ブラウザーはthiswindowに等しく設定されます。したがって、ドキュメント自体は間違っていませんが、イベント処理コードは、データコンテキストが未定義である可能性を防いでいません。短い順序で修正されると思います。

では、テンプレートのデータコンテキストを生成するものは何ですか?通常、ルートテンプレートにはデータコンテキストすらありません。つまり、Template関数はオブジェクトなしで呼び出されます。ただし、{{#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>
于 2013-03-01T02:50:09.377 に答える
13

関数の最初のパラメーターはイベントです。したがって、イベントのターゲットを使用して要素を取得できます。

Template.scores.events({
  'click .click-me': function (event, template) {
    console.log(event.target);
    $(event.target).text("O but I did!");
  }
});
于 2013-02-28T16:23:57.417 に答える