Ember 操作中的事件委托和全局“事件”对象

Event delegation and the global `event` object in Ember action

今天我了解了一些关于 Ember 中的 event delegation 的知识。整个事情正是我想在我的代码中使用的。不过有一个小问题。当我从

迁移时
<div ondragend={{action "dragEnd"}}></div>

<div {{action "dragEnd" on="dragEnd"}}></div>

然后我无法再在我的操作方法中获取 event 参数,问题是我需要它来访问 event.clientX/YThis answer 提到可以简单地删除参数 event 并像这样 "globally" 使用它

...
actions: {
  dragEnd() {
    event.blahblah...
  }
}

所以,我对这项技术有一些疑问:

  1. 谁能告诉我这有多合法?它没有在任何地方记录。
  2. 我是否理解正确,在我使用关闭操作 (<div ondragend={{action "dragEnd"}}></div>) 的情况下,它不会使用事件委托,即它将事件处理程序附加到 div 而不是如果我使用此模式 (<div {{action "dragEnd" on="dragEnd"}}></div>),body 就像根据 doc 所做的那样?

首先,您为什么要迁移到 {{action "dragEnd" on="dragEnd"}}? 那是最古老的 ember 动作风格,您不应该使用它们。 在使用 @action 修饰的新动作时使用 ondragend={{action "dragEnd"}} 或更好的 {{on "dragEnd" this.dragEnd}}。 如果您在 actions 哈希中有您的操作,请使用 {{on "dragEnd" (action "dragEnd")}}.

虽然 window.event 是浏览器的一项功能,但我不会使用它!参考MDN:

You should avoid using this property in new code

  1. 是正确的。基本上:

    • {{action修饰符(在{{action之前没有=使用)不会附加任何本机事件处理程序,而是等待事件冒泡到 body,其中事件必须已经注册(ember 为预设的事件列表执行此操作),然后使用 ember 内部处理机制来触发您的操作。 这基本上是旧时代的,你应该远离
    • 当您执行 eventname={{action 时,您会使用 {{action 助手 。虽然它与修饰符同名,但它根本不是一回事。 {{action 助手只是在您的 class 上的 actions 散列中找到操作,创建一个可能传递参数的绑定操作并将其绑定到正确的 this。然后将此结果操作分配给 HTML DOM 元素的 eventname 属性。 长期以来,这是一种非常普遍的做事方式,但从来都不是官方首选的方式。然而,它仍然是一个很好的做事方式。主要缺点是您不能向同一事件添加多个操作。所以 onclick={{action "foo}} onclick={{action "bar}} 在同一个元素上不起作用。
    • 新的 {{on 修饰符 是 ember octane 的新方法。它基本上运行 addEventListener。这允许像 {{action 修饰符那样添加多个处理程序,但使用的 ember 魔法要少得多,而是直接将事件添加到 DOM 元素,而不是使用自定义事件委托的任何奇怪魔法。但是它不执行任何操作查找。所以第二个参数直接需要是一个可以传给addEventListener的绑定函数。对于 ember octane,您可以直接在 class 上定义操作并向其添加 @action 装饰器,这基本上会创建一个具有正确 [=25= 的绑定函数] 上下文(它还将函数添加到 actions 散列以增加与 {{action 修饰符和助手的兼容性)。对于 classic 风格的动作,您可以使用 {{action helper 来查找动作,然后将其传递给 {{on 修饰符。那么你基本上会得到 {{on "click" (action "myAction")}}.

那么该怎么办:

  • 尽可能避免<button {{action "myAction" on="click"}}>。迁移远离
  • 当使用 classic 风格时 components/classes 和 Component.extend({ 使用 <button onclick={{action "myAction}}><button {{on "click" (action "myAction")}}>.
  • 当使用原生 classes and/or 微光组件并且你的动作用 @action 装饰器装饰时使用 <button {{on "click" this.myAction}}>.