Angular 2在每次按键时改变事件

更改事件仅在输入的焦点发生更改后才被调用。我怎样才能使事件在每次按键时触发?

<input type="text" [(ngModel)]="mymodel" (change)="valuechange($event)" />
{{mymodel}}

第二次绑定在每个按键上都发生变化。

672564 次浏览
<input type="text" [ngModel]="mymodel" (keypress)="mymodel=$event.target.value"/>
\{\{mymodel}}

更新

https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event

警告:由于此事件已弃用,您应该使用beforeinput或keydown代替。

通过将[(x)]语法分解为两部分来使用ngModelChange,即属性绑定和事件绑定:

<input type="text" [ngModel]="mymodel" (ngModelChange)="valuechange($event)" />
\{\{mymodel}}
valuechange(newValue) {
mymodel = newValue;
console.log(newValue)
}

它也适用于退格键。

<input type="text" (keypress)="myMethod(myInput.value)" #myInput />

归档.ts

myMethod(value:string){
...
...
}

我只是使用事件输入,它工作得很好如下:

在.html文件中:

<input type="text" class="form-control" (input)="onSearchChange($event.target.value)">

在.ts文件中:

onSearchChange(searchValue: string): void {
console.log(searchValue);
}

使angular ngModel保持同步的秘密事件是事件调用输入。因此,你的问题的最佳答案应该是:

<input type="text" [(ngModel)]="mymodel" (input)="valuechange($event)" />
\{\{mymodel}}

(按键)项目是你最好的选择。

让我们来看看原因:

  1. (变化)就像你提到的,只有当输入失去焦点时才会触发,因此用处有限。
  2. (键盘按键)会在按键时触发,但不会在某些按键(如退格键)时触发。
  3. (keydown)在每次按下键时触发。因此总是滞后1个字符;因为它获得了注册击键之前的元素状态。
  4. (按键弹起)是你最好的选择,因为它会在每次按键推送事件完成时触发,因此这也包括最近的字符。

所以(keyup)是最安全的,因为它…

  • 与(change)事件不同,在每次击键时都注册一个事件
  • 包括(按键)忽略的键
  • 没有延迟不像(keydown)事件

你要找的是

<input type="text" [(ngModel)]="mymodel" (keyup)="valuechange()" />
\{\{mymodel}}

然后通过访问.ts文件中绑定的this.mymodel来对数据做任何你想做的事情。

处理这种情况的另一种方法是使用formControl并在组件初始化时订阅它的valueChanges,这将允许你使用rxjs操作符来满足高级需求,如执行http请求,应用debounce直到用户写完一个句子,获取最后一个值并省略前一个值,等等。

import {Component, OnInit} from '@angular/core';
import { FormControl } from '@angular/forms';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';


@Component({
selector: 'some-selector',
template: `
<input type="text" [formControl]="searchControl" placeholder="search">
`
})
export class SomeComponent implements OnInit {
private searchControl: FormControl;
private debounce: number = 400;


ngOnInit() {
this.searchControl = new FormControl('');
this.searchControl.valueChanges
.pipe(debounceTime(this.debounce), distinctUntilChanged())
.subscribe(query => {
console.log(query);
});
}
}

在我的案例中,解决方案是:

[ngModel]="X?.Y" (ngModelChange)="X.Y=$event"

对于响应式表单,您可以订阅对所有字段或仅对特定字段所做的更改。

获取一个FormGroup的所有更改:

this.orderForm.valueChanges.subscribe(value => {
console.dir(value);
});

获取特定字段的更改:

this.orderForm.get('orderPriority').valueChanges.subscribe(value => {
console.log(value);
});

我一直在使用keyup在一个数字字段,但今天我注意到在chrome的输入有上升/下降按钮来增加/减少的值,这是不被keyup识别。

我的解决方案是使用keyup和更改一起:

(keyup)="unitsChanged[i] = true" (change)="unitsChanged[i] = true"

初步测试表明,这工作良好,将在进一步测试后,如果发现任何错误。

我用下面的代码在Angular 11中解决了这个问题:

<input type="number" min="0" max="50" [value]="input.to" name="to"
(input)="input.to=$event.target.value; experienceToAndFrom()">

并且,experienceToAndFrom()是我的组件中的一个方法。

PS:我尝试了以上所有的解决方案,但都不奏效。

这个问题有很多种答案。 然而,如果你想用另一种方式,特别是在你对change事件采取任何行动之前添加一些延迟,那么你可以使用带有angular形式valuechanges()的debounceTime()方法。这段代码需要添加在ngOnInit()钩子或创建一个单独的方法,并从ngOnInit()调用它
  ngOnInit(): void {
this.formNameInputChange();
}


formNameInputChange(){
const name = this.homeForm.get('name'); // Form Control Name
name?.valueChanges.pipe(debounceTime(1000)).subscribe(value => {
alert(value);
});
}
// this is reactive way..
homeForm = this.fb.group({
name:['']
});