【问题标题】:Angular 2 change event on every keypress每次按键时的Angular 2更改事件
【发布时间】:2016-05-23 09:52:14
【问题描述】:

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

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

btw 每次按键都会改变第二个绑定。

【问题讨论】:

    标签: angular


    【解决方案1】:
    <input type="text" [ngModel]="mymodel" (keypress)="mymodel=$event.target.value"/>
    {{mymodel}}
    

    【讨论】:

    • 有效,但奇怪的是退格键没有被识别为按键?
    • 您可能想改用keydownkeyup。有些键在keypress 上无法触发。另见stackoverflow.com/questions/4843472/…
    • 我已经尝试过 keydown、keyup 和 change 事件,但是当输入为 w 时,事件处理程序会向我报告空字符串;当输入是我们时,事件处理程序向我报告 w 作为输入。你能解释一下为什么会出现这种行为吗?
    • 使用按键。 keydown 上的输入尚未更改。
    • 这很奇怪,但我得到了输入滞后,在下一次按键之前该值不包含键入的值。
    【解决方案2】:

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

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

    它也适用于退格键。

    【讨论】:

    • 但是当在盒子语法中使用香蕉时,它只会改变模型,但你不能在改变事件上挂钩。
    • 这是最佳双向数据绑定的绝佳答案。应该是公认的答案!
    • 退格键不更新模型
    • 该解决方案是正确的。但是,请注意 ngModelChange 在值更新之前被触发。因此,此示例中的“newValue”包含没有您刚刚按下的键的模型 - 因此您那里没有更新的模型。如果您想获得最新的模型值,请使用 (keyup) 事件。
    • @SateeshKumarAlli 你有哪个版本的 Angular?对我来说,它确实在 Angular 6.1.3 中检测到退格
    【解决方案3】:
    <input type="text" (keypress)="myMethod(myInput.value)" #myInput />
    

    存档.ts

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

    【讨论】:

    • 欢迎来到 SO Ulric,请说明您的代码如何解决问题。
    【解决方案4】:

    我刚刚使用了事件输入,它工作正常如下:

    在 .html 文件中:

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

    在 .ts 文件中:

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

    【讨论】:

    • 我们如何延迟一段时间?
    • Edge 和 IE 浏览器不支持 (input) 事件。在 Edge 浏览器中有什么替代方法?
    • 谢谢,非常适合 Angular 6。
    • 在变更检测上花了很多时间,什么都没有。最终,找到了平静。这次真是万分感谢! PS:我的问题与角度[formGroup]有关,在找到这篇文章之前我正在使用(更改)。不知道(输入)会起作用。
    【解决方案5】:

    保持 Angular ngModel 同步的秘密事件是事件调用 input。因此,您的问题的最佳答案应该是:

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

    【讨论】:

    • 它对我有用@AndreiDiaconescu
    • Edge 和 IE 浏览器不支持 (input) 事件。在 Edge 浏览器中有什么替代方法?
    【解决方案6】:

    (keyup)事件是您最好的选择。

    让我们看看为什么:

    1. (更改) 就像您提到的那样,仅当输入失去焦点时才会触发,因此用途有限。
    2. (keypress) 在按键时触发,但不会在某些击键时触发,例如退格键。
    3. (keydown) 每次按下一个键时触发。因此总是滞后 1 个字符;因为它在按键注册之前获取元素状态。
    4. (keyup) 是您最好的选择,因为它会在每次按键事件完成时触发,因此这也包括最近的字符。

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

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

    【讨论】:

    • 正如其中一个答案中提到的,输入事件非常有效。 keyup 肯定是最安全的选择之一,但 input 事件比 keyup 领先一步。 keyupinput 不同,如果文本框的值通过任何其他方式(例如绑定。
    • 萨加尔,非常感谢。 这应该是已接受的答案,因为它是唯一一个实际解决 (change) 以及解决方法和其他一些问题的答案。接受的答案完全糟透了!
    • 这应该是公认的最安全的答案,因为它是原生的,可以让您完全控制并且非常具有表现力,因为阅读它的每个人都知道事件何时触发。
    • @ThariqNugrohotomo 不,它不会。如果您正在寻找类似的东西,请使用(输入)。
    • (keyup) 帮我退格键击,非常感谢!
    【解决方案7】:

    你要找的是

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

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

    【讨论】:

      【解决方案8】:

      处理这种情况的另一种方法是使用 formControl 并在初始化组件时订阅它的 valueChanges,这将允许您使用 rxjs 运算符来满足高级要求,例如执行 http请求,应用去抖动直到用户写完一个句子,取最后一个值并省略前一个,...

      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);
            });
        }
      }
      

      【讨论】:

      • 这是完美的。当将其用于异步 http 请求时,这可以降低闲聊噪音。还已经设置了更改事件侦听器。杰出的!谢谢!
      • 在多个控件的情况下,可以使用FormGroup应用相同的代码
      【解决方案9】:

      就我而言,解决方案是:

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

      【讨论】:

        【解决方案10】:

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

        获取 FormGroup 的所有更改:

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

        获取特定字段的变化:

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

        【讨论】:

        • 注意它只会在模糊时触发
        【解决方案11】:

        我一直在数字字段上使用 keyup,但今天我注意到在 chrome 中输入有向上/向下按钮来增加/减少 keyup 无法识别的值。

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

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

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

        【讨论】:

          【解决方案12】:

          我设法通过使用以下代码在 Angular 11 中解决了这个问题:

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

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

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

          【讨论】:

            【解决方案13】:

            已通过多种方式回答了这个问题。 但是,如果您想查看另一种方式,特别是在对更改事件采取任何操作之前添加一些延迟,那么您可以使用带角度形式 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:['']
              });
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-07-09
              • 1970-01-01
              • 2017-05-25
              • 1970-01-01
              • 2016-08-10
              • 1970-01-01
              相关资源
              最近更新 更多