为什么Meteor有一个奇怪的事件处理程序语法?

时间:2014-02-22 14:35:35

标签: javascript-events meteor

让我对Meteor感到困扰的是事件附加到模板的方式。关于不能使用jQuery并不是一个抱怨,但我不能不怀疑这些写入方式有问题。

以下是一个简洁的例子:

Template.input.events = {
    'mousedown input#message' : function(event){
        console.log('the mouse was pressed');
    },

    'touchstart input#message' : function(event){
        console.log('a finger was pressed');
    },
}

有人可以向我解释为什么事件名称和查询选择器会合并为一个字符串,如'mousedown input#message'吗?我只是不明白为什么有人会想要这样做的东西。

如果是我,我会将事件嵌套在每个选择器下面。注意:这段代码不起作用,这就是我认为的样子。

Template.input.events = {
    'input#message' : {
        'mousedown' : function(event){
            console.log('the mouse was pressed');
        },

        'touchstart' : function(event){
            console.log('a finger was pressed');
        }
    }
}

1 个答案:

答案 0 :(得分:8)

一个原因是您可以使用没有选择器的事件名称将事件附加到模板本身。一个常见的用例是将submit事件处理程序附加到包含表单的模板:

Template.someForm.events({
  "submit": function() {
    /*...*/
  }
});

此外,您可以使用逗号分隔列表对多个事件类型使用相同的处理函数。这甚至允许您对完全不同的元素上的不同类型的事件使用相同的事件处理程序。也许你想要创建一个事件处理程序,当用户单击一个保存按钮或按下带有模板中某些内容的“s”键时触发该事件处理程序。 Meteor的事件系统允许在事件映射中定义它,只有一个定义:

Template.someTemplate.events({
  "keyup, click .save": function(event, template) {
    if (event.type === "keyup" && event.which !== 83) return;

    // save
  }
});

在你的情况下,我可能会这样做:

Template.input.events({
  "mousedown #message, touchstart #message" : function(event){
    // you can do different things by examining event.type
  }
});

然而,尽管Meteor的事件地图具有优势,但如果您愿意,也可以轻松使用您的格式。这是一个函数,它以您的格式获取事件映射并将其转换为Meteor事件映射:

// Call it whatever you want
var transformEvents = function(selectorEvents) {
  return _.reduce(selectorEvents, function(meteorEvents, events, selector) {
    _.each(events, function(handler, eventType) {
      meteorEvents[eventType + " " + selector] = handler;
    });
    return meteorEvents;
  }, {});
};

只需通过此方式传递您的事件地图样式,它就会将其转换为Meteor兼容的:)

就无法使用jQuery而言,其原因在于Meteor的事件系统会自动将您的事件处理程序范围限定为模板实例,而单独使用jQuery非常困难。从技术上讲,我认为没有什么能阻止你使用jQuery事件,但这会引起Meteor的事件系统避免的一些重大问题。