Обнаружение изменения угловой формы - PullRequest
0 голосов
/ 13 сентября 2018

Я использую угловые формы, и я хотел бы использовать их встроенное обнаружение изменений для реализации функциональности в моем приложении.Когда пользователь нажимает кнопку, он должен видеть диалоговое окно, только если он / она внесла какие-либо изменения в форму.

У меня есть переменная changesMade:

private changesMade: boolean;

Это мой код TSформы:

this.carForm = new FormGroup({
        name: new FormControl('', [
            Validators.required,
            Validators.pattern('[a-zA-Z ]*'),
            Validators.minLength(1),
            Validators.maxLength(10)
        ])});

Это мой HTML-код формы:

<form [formGroup]="carForm">
        <ion-item>
          <ion-label  stacked>car name</ion-label>
          <ion-input type="text" [(ngModel)]="carname" formControlName="name"></ion-input>
        </ion-item>
</form>

Вот мой смоделированный (на данный момент) вызов службы, где я подписываюсь на изменения формы после того, как я 'мы устанавливаем значение carname, которое привязано к входу

setTimeout(()=>{
  this.carname = "BMW";
  this.carForm.valueChanges.subscribe(val => {
  this.changesMade = true;
    });
}, 44)

Проблема здесь в том, что, хотя я не трогал форму, this.changesMade получает значение true.

ПРИМЕЧАНИЕ. Если я переместу часть кода подписки в ngAfterViewInit, он все равно установит для changeMade значение true, даже если я не вводил значения:

  ngOnInit(){
    //simulated server call
    setTimeout(()=>{
      this.carname = "BMW";

    }, 44)
  }
      ngAfterViewInit(){
this.carForm.valueChanges.subscribe(val => {
      this.changesMade = true;
        });
    }

Я создал STACKBLITZ демонстрирует проблему.Как я могу заставить его выполнить this.changesMade = true; только тогда, когда я на самом деле физически коснулся ввода в пользовательском интерфейсе?

Ответы [ 3 ]

0 голосов
/ 13 сентября 2018

Вы используете два подхода в одной форме:

Вам нужно выбрать один.

Это решение с реактивными формами:

1.Удалить модель из шаблона

<ion-input type="text" formControlName="name"></ion-input>

2.Добавить rxjs / first для изменений обновленияСделано один раз и автоматическая отмена подписки

import 'rxjs/add/operator/first';

3.Удалить свойство carName из компонента и обновить его с помощью patchValue

ngOnInit() {
  //simulated server call
  setTimeout(() => {
    this.carForm.patchValue({ name: 'BMW' })
    this.carForm.valueChanges.first().subscribe(val => {
      this.changesMade = true;
    });
  }, 44)
}

Пример Stackblitz

0 голосов
/ 14 сентября 2018

Таким образом, помещая подписку в конец стека вызовов (с setTimeout (0)), все, кажется, работает как ожидалось:

//simulated server call
setTimeout(()=>{
  this.carname = "BMW";
  setTimeout(function(){
  this.carForm.valueChanges.subscribe(val => {
  this.changesMade = true;
    });
  }.bind(this), 0)

}, 44)

Вот STACKBLITZ , демонстрирующий его работу.

UPDATE

Поскольку использование реактивных форм с ngModel в Angular 6 + не рекомендуется, , в аналогичных случаях лучше заменить реактивные формы шаблонно-управляемыми формами.

0 голосов
/ 13 сентября 2018

Проблема здесь в том, что вы смешиваете реактивные формы и ngModel. Поскольку вы использовали ngModel в своем шаблоне и установили this.carName = 'BMW' в своем компоненте, это вызывает обнаружение изменений, и formGroup обновляется, и ваш флаг changesMade становится истинным. Удалите ngModel и получите значения формы, используя API реагирующей формы: https://angular.io/guide/reactive-forms#reactive-forms-api.

Я обновил STACKBLITZ: https://stackblitz.com/edit/ionic-qkjeu6?file=pages%2Fhome%2Fhome.ts

...