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

Wra*_*ing 4 javascript-events meteor

令Me困扰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');
    },
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以向我解释为什么事件名称和查询选择器将组合成一个单独的字符串'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');
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

sbk*_*ing 8

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

Template.someForm.events({
  "submit": function() {
    /*...*/
  }
});
Run Code Online (Sandbox Code Playgroud)

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

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

    // save
  }
});
Run Code Online (Sandbox Code Playgroud)

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

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

然而,尽管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;
  }, {});
};
Run Code Online (Sandbox Code Playgroud)

只需通过它传递你的事件地图样式,它将把它变成一个兼容Meteor的:)

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

  • 与大多数事情一样,这是一种平衡行为.是的,订单决定了它; 事件名称是必需的,选择器是可选的.正如[在文档中解释](http://docs.meteor.com/#eventmaps),格式将始终遵循`"eventtype"`,`"eventtype selector"`和`"event1,event2"的某种组合. .这确保没有歧义,但是这样做的一个限制是你不能像在CSS中那样使用逗号分隔的选择器.如果你有一个带有两个参数的函数,你就失去了将一个处理程序分配给同一个映射的能力,比如"click.current,mouseenter .next,keydown". (2认同)