Angular2 阻止在指令中按下回车键时提交表单

Angular2 prevent form submission on press of the enter key from within a directive

我有一个在 <input type="text" /> 元素上实现的自定义指令:

<form #testForm="ngForm" (ngSubmit)="submit()">
    <input type="text" name="testInput" testDirective />
    <button type="submit">Submit</button>
</form>

该指令在 keyup 事件上有一个 HostListener

@Directive({
    selector: '[testDirective]'
})
export class TestDirective {
    @HostListener('keyup', ['$event'])
    onkeyup(event: any)
    {
        // Do stuff

        if (event.keyCode == 13) { // 13 = enter
            event.stopPropagation();
            return false;
        }
    }
}

如您所见,我根据其他问题的建议使用了 event.stopPropogation()return false 但这不起作用,并且在按下回车键时仍在提交表单.

但是,如果我将 (keydown.enter)="$event.preventDefault()" 放在输入元素本身上,它会产生预期的效果并阻止表单提交。

<input type="text" name="testInput" testDirective (keydown.enter)="$event.preventDefault()" />

这种方法对我来说不是特别理想,因为我想以编程方式控制何时按下回车键禁用表单提交。

有人知道为什么 stopPropagation() / return false 方法在这种情况下不起作用吗?

触发是由于您在一个表单中,并且您点击了一个提交类型的输入。

删除您的表单标签,通过带有点击事件的按钮更改您的输入,您就可以开始了。

这两种方法的区别在于,一种使用 event.stopPropogation(),另一种使用 event.preventDefault()。请注意,在有效的那个中,您使用的是 event.preventDefault()。从 Web API docsEvent.stopPropogation 执行以下操作:

Prevents further propagation of the current event in the capturing and bubbling phases.

换句话说,事件仍然会触发,但不允许在 DOM 树中冒泡。为了真正停止事件,您需要使用 Event.preventDefault,就像您在第二种方法中使用的输出绑定中一样。此外,来自 Web API docs:

[Event.preventDefault] tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be.

本质上,这个 onkeyup 函数应该做你想做的事:

  @HostListener('keyup', ['$event'])
  onkeyup(event: any) {
    // Do stuff

    if (event.keyCode == 13) { // 13 = enter
        event.preventDefault();
        return false;
     }
   }

错误只是一个 keyup/down 错误:

@Directive({
  selector: '[testDirective]'
})
export class TestDirectiveDirective {
  @HostListener('keydown', ['$event']) //keydown, not keyup
  onKeyDown(event: any) {
    // Do stuff
    if (event.keyCode === 13) { // 13 = enter
      return false;
    }
  }
}

顺便说一句,stopPropagation 在这种情况下也是不必要的,至少从我的(公认的有限)测试来看是这样。 YMMV