Как обнаружить изменения в поле ввода при вводе [Angular] - PullRequest
2 голосов
/ 11 апреля 2020

Я новичок в Angular. Я пробую несколько простых вещей. У меня есть поле ввода. Я просто хочу обнаружить изменения. Я хочу вызывать некоторый код всякий раз, когда я печатаю в поле. Я проверил эти статьи:

  1. Документация: Angular - onChanges
  2. В чем разница между OnChanges и DoCheck в Angular 2?
  3. Документация: Angular - перехватчики жизненного цикла
  4. переполнение стека: в Angular 4 перехват ngOnChanges не срабатывает на входе

Вот мой код:

my-component.component. html

<input [(ngModel)]="text">

my-component. component.ts

import { Component, OnInit, DoCheck } from '@angular/core';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponentComponent implements OnInit, DoCheck {

  text="hello world";

  constructor() { }

  ngOnInit() {
  }

  ngOnChanges(changes: SimpleChanges) {
    // changes.prop contains the old and the new value...
  }

  // ngDoCheck() { // TRIED THIS ALSO
  //   console.log("Changes detected")
  // }
}

Две важные сведения:

  1. Я также пытался DoCheck, но это не то, что я хотеть. Я хочу видеть, изменилось ли значение только для поля ввода или нет. Но ngDoCheck будет вызываться после каждого небольшого изменения в остальных компонентах, так как он использует zone.js (я читал это где-то).

  2. Я не могу использовать (keydown) также, как я хочу реализовать проверочный код позже. Я хочу, чтобы проверка происходила при вводе. Но с keydown я заметил, что я должен вызывать код проверки с некоторым нажатием клавиши, даже после того, как введенное значение действительно, скажем, Дата / Время.

Сохранение выше двух точек пожалуйста, поправьте меня. Вот стекблиц .

Ответы [ 4 ]

2 голосов
/ 11 апреля 2020

Angular обрабатывает само обнаружение изменений. Вам просто нужно подключиться к логике c, когда это произойдет. В большинстве случаев это будет предпочтительнее использования списков событий, которые предлагаются большинством других ответов в этой теме.

При каждом изменении ввода angular обращается к переменной, в которой задана строка.

Один из способов сделать что-то, когда переменные изменится, - это использовать get ter и set ter.

  // create an internal variable (do not change manually)
  private _text;

  // getter function, called whenever the value is accessed
  get text(){
    console.log("the value was accessed")
    return this._text
  }

  // setter function, called whenever the value is set
  set text(text){
    this._text = text
    console.log("the value was set")
  }

Я также отредактировал ваш stackblitz, чтобы включить пример. https://stackblitz.com/edit/angular-6qvlrh

Все остальное остается прежним. И вам просто нужно использовать ngModel для текста.

<input [(ngModel)]="text">
1 голос
/ 11 апреля 2020

Я думаю, что все вышеприведенные ответы верны. Мне нравится метод getter-setter, хотя он добавляет несколько строк кода. На всякий случай, если вы хотите протестировать третий способ отслеживания изменений, вы добавили свой код: https://stackblitz.com/edit/angular-myrrqo

Он использует @ViewChildren и подписку на наблюдаемый valueChanges:

export class MyComponentComponent implements AfterViewInit  {

  text="hello world";
  second="hi angular";

  @ViewChildren(NgModel) myInputRef: QueryList<NgModel>;

  ngAfterViewInit() {
    this.myInputRef.forEach(ref =>
      ref.valueChanges.subscribe(val =>
        console.log(`${ref.name}'s value changed to ${val}`)
      )
    );
  }
}

В шаблоне:

<input [(ngModel)]="text" name="firstInput">
<input [(ngModel)]="second" name="secondInput">

Я добавил второй элемент ввода, чтобы показать, что если у вас более одного элемента с двусторонним связыванием, вы должны использовать @ViewChildren , Если бы у вас был только один элемент, вы могли бы использовать @ViewChild(NgModel) myFirstInput: NgModel;, а код был бы еще проще.

1 голос
/ 11 апреля 2020

Эти 2 изменения необходимы для отслеживания изменений на входе:

  1. Обновите шаблон компонента, указав значение привязки, и укажите (изменение) событие.
  2. Обновите скрипт компонента, указав метод onChange .

Рабочий раствор:

1. my-component.component. html

<input [(value)]="text" (change)="onChange($event)">

2. my-component.component.ts

import { Component, OnInit, DoCheck } from '@angular/core';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponentComponent {

  text="hello world";
  constructor() { 
    console.log("Text = " + this.text)
  }

  onChange(event: any) {
       this.text = event.target.value;
       console.log("New value = " + event.target.value)
  };
}
1 голос
/ 11 апреля 2020

вы можете использовать input(): Например:

HTML:

<input [(ngModel)]="text" (input)="sendTheNewValue($event)">

TS:

let value:string;

sendTheNewValue(event){
this.value = event.target.value;
}

в вашем примере: HTML:

<input [(ngModel)]="text" (input)="change($event)">
<div>the input value is : {{text}}</div>

TS:

import { Component, OnInit, DoCheck, SimpleChanges, OnChanges, Input   } from '@angular/core';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponentComponent implements OnInit, OnChanges  {

  text="hello world";

  @Input() name: String = "abc"

  constructor() { }

  ngOnInit() {
  }

  ngOnChanges(changes: SimpleChanges) {
    // changes.prop contains the old and the new value...
    console.log("Changes detected");
  }

  change(event){
    this.text = event.target.value;
  }

  // ngDoCheck() {
  //   console.log("Changes detected");
  // }
}
...