1

我有一个想要检测更改的反应形式。例如,当用户查看产品时,会打开一个“查看产品”页面,在所有表单字段中填写该产品的详细信息。如果对表单中的任何值进行了更改,我希望启用“保存”按钮(默认情况下禁用)。但是,如果用户撤消更改或恢复到加载时的状态,“保存”按钮将再次被禁用。

这可能吗?我见过一些人这样做,其中 angular 检测到表单更改并使表单“脏”,但是一旦表单被弄脏,将状态更改回原始状态并不容易或直观。我还阅读了人们在哪里将初始产品详细信息加载到本地存储中,并将当前状态的表单值 JSON 与本地存储 JSON 进行比较,并基于此启用/禁用按钮。有没有人有首选或更好的方法?

谢谢

4

2 回答 2

3

当初始数据到达时,将其作为组件属性保存在本地。然后,您可以随时将其与表单的当前值进行比较,以确定是否发生了变化。

你需要:

  • initValues, 起始表单值(在用户交互之前)

  • disableSaveBtn:boolean绑定到模板中按钮的属性:[disabled]="disableSaveBtn"

  • valuesMatch(val1,val2):boolean将比较表单的两个模型并true在它们匹配时返回的函数

每次表单值更改时进行比较。由于您使用的是反应形式,因此您可以只听valueChanges可观察的

// will emit every time a form control value is changed
this.form.valueChanges.subscribe(newValues => {
    // disable the button if new value matches initial value
    this.disableSaveBtn = this.valuesMatch(newValues, initValues)
})
于 2017-06-28T01:59:47.853 回答
1

基于 BeetleJuice 提到的内容:

找出脏东西:JSON stringify 比较适用于深度嵌套的对象,并且似乎比单独跟踪所有表单控件更便宜,因为浏览器需要查看所有将创建的可观察对象。

  patchValueLocation(yourFormValues){
    this.form.patchValue(yourFormValues);
    this.createReference(this.formGroup.value)
    this.loading = false;
  }

  private createReference(obj: any){
    this.reference = JSON.stringify(obj)
  }

  ngOnInit() {
    this.form.valueChanges.subscribe(newValues=> {
      if(!this.loading){
        const hasChanges = !( JSON.stringify(newValues) === this.reference );
        this.dirty = hasChanges;
      }
    })
  }

如本文档中所示,您也可以收听单个表单控件。

https://alligator.io/angular/reactive-forms-valuechanges

ngOnInit(): void {
  this.myForm.get('name').valueChanges.subscribe(val => {
    this.formattedMessage = `My name is ${val}.`;
  });
}
于 2020-05-12T16:28:07.097 回答