EmberJS - 如何不与组件中的动作和事件发生冲突

EmberJS - How not to conflict with actions and events in components

我认为组件中的模板操作和事件之间存在问题。

据我了解,所有操作点击都将首先执行并冒泡。 最后,组件中的事件也会被执行。 好像有两个并行的栈一个接一个执行。

如果组件模板中有这样的内容:

Hello <button onclick={{action 'clickMe'}}>Click me</button>

在相应的 javascript 文件中:

click: function() {
   alert('second message');
}

您不确定是否会显示第二条消息。如果在动作堆栈中调用了event.stopPropagation()(在动作'clickMe'中没有必要),则不会显示第二条消息。

这是一个小游戏:https://ember-twiddle.com/c9a014a0c19851596d5e1184c9967cbc

有没有绕过这个问题的解决方案?

当你说 <button onclick={{action 'clickMe'}}>Click me</button> - 它与 ember 无关,它只是为点击事件注册的正常功能。

当你说,<button {{action 'clickMe'}}>Click me</button>这里Ember会接管(我不太确定我在说什么,但一般来说事件处理将由Ember处理)。

twiddle1 - Ember 正在处理所有事件处理(即,<div {{action 'test'}}> 然后你可以期望,事件从子组件传播

输出:

action click from my-child
click from my-child
action click from my-parent
click event from my-parent

整洁,这是预期的行为。即使您调用 event.stopPropagation 父组件,它也没有做任何事情。

twiddle 2 - 浏览器正在处理事件,即 <div onclick={{action 'test'}}>

输出:

action click from my-child
action click from my-parent
click from my-child
click event from my-parent

这里可以先将它的触发动作click从child传到parent,再调用相应组件的click handler。在这种情况下,如果您在父操作点击处理程序中调用 event.stopPropagation(),那么 ember 将没有机会调用 parent/child 组件的点击处理程序。

这就是您遇到的问题,要解决您可以从 <div onclick={{action 'clickMe'}}> 移动到 <div {{action 'clickMe'}}>

我反对@kumkanillam 在他的回答中提出的建议:“要解决,您可以从 <div onclick={{action 'clickMe'}}> 移动到 <div {{action 'clickMe'}}>。”

第一个(您在问题中使用的原始那个)是 ember 的 closure action 在起作用 :) 它更强大;这样你就可以 return 从父组件到子组件的值;因为它实际上是一个函数,其中 this 上下文由下面的 ember 正确设置,您可以急切地检测未处理的操作。另一方面,@kumkanillam 建议的通常命名为 "action in element space"。 Ember.

的低级别 DOM 事件处理

请看下面精彩的article解释为什么closure actions摇滚!关于你的问题;我建议尽可能多地使用 closure actions 并通过将相关代码部分移动到操作处理来避免 DOM 事件操作处理,正如@DanielKmak 在他的评论中已经提到的那样。我个人更喜欢尽可能多地关闭操作,并且只在不可避免时依赖 DOM 事件处理程序(例如 box-content 中的 click 和你的 twiddle 中的 my-component )。