Подтвердить что ты не робот

Контекст "this" в обработчиках событий шаблонов Meteor (с использованием Handlebars for templating)

Быстрый вопрос о контексте обработчиков событий для шаблонов в Meteor (с Handlebars).

  • В разделе Документация по экземплярам шаблона (http://docs.meteor.com/#template_inst) упоминается, что "Объекты экземпляра шаблона найдены как значение этого в созданном, визуализированном, и разрушенные обратные вызовы шаблонов и как аргумент обработчикам событий"
  • В разделе "Шаблоны" (http://docs.meteor.com/#templates) говорится:" Наконец, вы можете использовать объявление событий в функции шаблона для настройки таблицы обработчиков событий. Формат документируется на картах событий. Этот аргумент для обработчика событий будет контекстом данных элемента, вызвавшего событие.

Ну, это только отчасти верно. Позвольте использовать пример из документов:

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

Здесь контекст "this" обработчика событий "click.givePoints" действительно является экземпляром шаблона 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" всегда является экземпляром шаблона.

Я предполагаю, что мой реальный вопрос: это что-то связано с

  • ошибка в Handlebars, Meteor или где-то посередине?
  • немного неполная документация по шаблонам?
  • меня полностью неверно истолковываю документы или не понимаю что-то фундаментальное о Метеор или Рульберов?

Спасибо!

4b9b3361

Ответ 1

В этом видео объясняются понятия:

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

Прямой ответ на ваш вопрос:

Этот атрибут внутри обработчика события должен указывать на контекст данных. Но иногда контекст данных undefined. Когда вы используете Function.prototype.call(thisArg, ...) в JavaScript, если thisArg undefined (например, dataContext undefined), браузер установит this равным окну. Таким образом, документы не ошибаются сами по себе, но код обработки событий не защищает от возможности использования контекста данных undefined. Я предполагаю, что это будет исправлено в короткий срок.

Итак, что создает контекст данных для шаблона? Обычно ваш корневой шаблон даже не имеет контекста данных. Другими словами, функция Template вызывается без объекта. Но если вы используете вспомогательный блок {{#with или итератор {{#each, будет создан контекст данных для каждого элемента в списке или в случае с помощником - объектом.

Пример:

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>

Ответ 2

Первым параметром функции является событие. Таким образом, вы можете использовать цель события, чтобы захватить ваш элемент.

Template.scores.events({
  'click .click-me': function (event, template) {
    console.log(event.target);
    $(event.target).text("O but I did!");
  }
});