Javascript Angular(2 +) 检测 Angular 形式(反应式)中的数据是否被更改
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/50405358/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular(2 +) Detect if data in an Angular form (reactive) was changed
提问by AllmanTool
I have some form and button to save it. The button must only be enabled when there are unsaved changes (inputs) on the form.
我有一些表格和按钮来保存它。仅当表单上有未保存的更改(输入)时才必须启用该按钮。
<form>
    <div>
    ... (inputs)
        <span (click)="save()"> Save </span>
    </div>
</form>
Is there some build-in mechanism for form dirty check in Angular 5? What is the easiest way to implement this scenario ?
Angular 5 中是否有一些用于表单脏检查的内置机制?实现此场景的最简单方法是什么?
回答by
Yes there is: I highly advise you to take a look at the documentation of reactive forms.
Apart from that, the built-in mechanism is only for checking the state of the form:
除此之外,内置机制仅用于检查表单的状态:
touchedmeans the user has entered the formdirty/!pristinemeans the user has made a modification
touched表示用户已输入表单dirty/!pristine表示用户进行了修改
But if you want to handle changes made, you should not use that: if your username changes its username from "foo", to "bar", then back to "foo", there is no changes in your form, so the user should not have to send the said form.
但是,如果您想处理所做的更改,则不应使用它:如果您的用户名将其用户名从“foo”更改为“bar”,然后又回到“foo”,则表单中没有任何更改,因此用户应该不必发送上述表格。
Instead, what I advise you is to make a function that compares the form to the original value of your object. Here is how you can do it:
相反,我建议您创建一个函数,将表单与对象的原始值进行比较。您可以这样做:
// Creates a reference of your initial value
createReference(obj: any) {
  this.reference = Object.assign({}, obj);
}
// Returns true if the user has changed the value in the form
isDifferent(obj: any, prop: string) {
  return this.reference[prop] !== obj[prop];
}
submitForm(form: any) {
  // ... Business code ...
  hasChanges = false;
  for (let prop in form) {
    if (this.isDifferent(form, prop)) { hasChanges = true; }
  }
  // If no changes, cancel form submition
  if (!hasChanges) { return; }
}
回答by Chris
When you are working with reactive forms (https://angular.io/guide/reactive-forms), there is a property pristineand a property dirtyon the form-group and the control. Should look similar to this:
当您使用反应式表单 ( https://angular.io/guide/reactive-forms) 时,表单组和控件上有一个属性pristine和一个属性dirty。应该类似于:
<form form-group="myGroup">
  <div>
    <input type="text" formControlName="ctrl1">
    ... (further inputs)
    <span><button (click)="save()" [disabled]="myGroup.pristine"> Save </button></span>
  </div>
</form>
and the .ts file:
和 .ts 文件:
import { Component, .... } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({...})
export class YourFancyComponent {
  myGroup: FormGroup;
  constructor(private( formBuilder: FormBuilder) {
      this.myGroup = this.formBuilder.group({
        'ctrl1': 'defValue',
        'ctrl2': 'defaultValue2'
      });
  }
}
For template-driven forms (according to https://angular.io/guide/forms#track-control-state-and-validity-with-ngmodel) the css class of the modified input control changes from ng-pristineto ng-dirtybut that doesn't help with the save button.
对于模板驱动的表单(根据https://angular.io/guide/forms#track-control-state-and-validity-with-ngmodel)修改后的输入控件的 css 类从 更改为ng-pristine,ng-dirty但没有帮助保存按钮。

