考虑以下演示https://stackblitz.com/edit/angular-pur1dt
我有反应式表单控件,同步验证程序和错误消息显示在字段下面无效时 .
当控制失去焦点时,将触发验证 . 控件下方有一个带有点击处理程序的按钮 . 问题是,当我单击按钮时,控件失去焦点,验证发生,显示错误消息并向下移动按钮 . 据说这可以防止点击处理程序执行 . 任何建议为什么会发生这种情况以及如何解决问题?
我已经用评论更新了演示 . 注意:输入下方的仅按钮将重现该问题 . 第一次单击它后, Headers 不会更新 .
3 回答
该问题似乎与触发订单的DOM事件有关
据MDN称:
https://developer.mozilla.org/en-US/docs/Web/Events/click
在给定的示例中,元素会在您输入的那一刻移动 - 因为验证会立即发生,显示错误并重新定位按钮 .
因此鼠标 is down when 在按钮上方时,但当 its up 时 - 按钮被重新定位 . 所以
click
wont be triggered on the button有几种方法可以解决这个问题:
on
mousedown
延迟错误显示隐藏错误,直到
mousedown
和mouseup
都发生,如果mousedown
发生在按钮上等
以下是
mousedown
事件处理的示例https://jsfiddle.net/gjbgqqpo/希望这可以帮助 :)
这个问题在GitHub的issue #7113中讨论过 . 这是因为在单击按钮有机会完成并触发
click
事件之前,当输入字段失去焦点时执行验证 .一种可能的解决方法是使用标志来隐藏消息,同时单击按钮,如this stackblitz所示 . 在下面的代码中,在
mousedown
事件上单击开始时设置isClicking
标志,并在click
事件完成时重置该标志 .您可以通过将
setTimeout
替换为在mousedown
事件处理程序中捕获鼠标的过程来更改该解决方案,并在捕获丢失时重置isClicking
. 它将解释用户在未完成点击的情况下离开按钮的情况 .好的,我想我会跟着 . 单击下方按钮时,您不希望进行验证 .
触发验证的原因是因为表单输入上的
autofocus
. Angular "By default, the value and validity of a control updates whenever the value changes." See FormControl . 该控件正在将name.untouched
从false
更改为true
.如果您向模板添加一些额外的调试绑定,您可以观察到这种情况 . 例如
如果要在用户单击下方按钮时隐藏错误消息,则应在调用
onClick2()
时删除autofocus
或重置表单的验证 . 或者,您只能在表单出错时显示错误消息 . Angular说A control is untouched if the user has not yet triggered a blur event on it.
单击下方按钮会导致模糊事件 .为什么不在错误消息上更改模板绑定