如何检查表单中的更改的可用性 Angular 2 通过

我有一个带有多个数据字段和两个按钮的表单。 只有用户对表单进行一些更改时,才能启用按钮。 我试图用:


this.form.valueChanges.subscribe/data => console.log/'form changes', data//;


但最初在窗体也加载时会检测到更改。 是否有其他方法可以检查表单中的任何变化吗? 只有在用户对字段更改时才被调用,而不是加载表单时才被调用。 下面是我的代码 html 和 typescript:

profile.html:


<section>
<div>
<form [formgroup]="form">
<fieldset>
<div class="panel-group m-l-1 m-r-1 accordion vertical-scroll" id="">
<div class="form-group required no-gutter">
<label for="firstname"> First Name:</label>
<div class="col-md-7 col-lg-6">
<input aria-required="true" class="form-control" formcontrolname="firstname" id="firstname" maxlength="35" name="firstname" placeholder="" size="128" title="firstname" type="text"/>
</div>
</div>
</div>
</fieldset>
<div>
<button "="" ="save="" class="btn btn-primary" click="" type="button">Save</button>
<button "="" ="cancel="" class="btn btn-primary" click="" type="button">Cancel</button>
</div>
</form>
</div>
</section>


profile.component.ts:


export class ProfileComponent implements OnInit, AfterViewInit, OnChanges {
public form: FormGroup;

constructor/private formBuilder: FormBuilder, private app: Application/ {

}

loadForm//: void {
this.form = this.formBuilder.group/{
firstname: [this.app.firstName, Validators.required]
}/;
this.form.valueChanges.subscribe/data => console.log/'form changes', data//;

}

save//: void {

}

cancel//: void {

};

ngOnInit// {
this.loadForm//;
}

ngAfterViewInit// {
this.loadForm//;
}
}
已邀请:

奔跑吧少年

赞同来自:

您可以使用值
.dirty

/或者
.pristine

/, 确定用户是否使用过 UI 要更改控制值:


<button "="" ="save="" [disabled]="!form.dirty" class="btn btn-primary" click="" type="button">Save</button>
<button "="" ="cancel="" [disabled]="!form.dirty" class="btn btn-primary" click="" type="button">Cancel</button>


[/url]
dirty : boolean 如果用户更改了该值,则控制是脏的
在 UI.

请注意,程序更改为控制值不会标记
肮脏的。

touched: boolean 在用户之后被标记为标记
它有一个模糊事件。

君笑尘

赞同来自:

逻辑值的问题 .dirty 和 .pristine 这是,一旦改变,他们就不会退回,即使您取消了您所贡献的所有更改。 我设法通过创建跟踪所有表单中的更改的类来找到一种方法来解决此问题,并将检查复制值以及表单的源值。 因此,如果取消用户更改,表单可能会返回到优先级状态,或者可能会给观察到的逻辑值 /ReplaySubject/, 您可以提供和订阅它。

福利将大致如下:


private _formIntactChecker:FormIntactChecker;

constructor/private _fb: FormBuilder/ {

this._form = _fb.group/{
...
}/;

// from now on, you can trust the .dirty and .pristine to reset
// if the user undoes his changes.
this._formIntactChecker = new FormIntactChecker/this._form/;

}


或者,而不是重置逻辑值 .pristine/.dirty, 可以将该类配置为每当表单随附的完整修改时发出逻辑值,反之亦然。 真正的布尔表示表格再次完好无损,而错误的布尔表示表单不再完好无损。

以下是您将如何使用它的示例:


private _formIntactChecker:FormIntactChecker;

constructor/private _fb: FormBuilder/ {

this._form = _fb.group/{
...
}/;

var rs = new ReplaySubject//

rs.subscribe//isIntact: boolean/ => {
if /isIntact/ {
// do something if form went back to intact
} else {
// do something if form went dirty
}
}/

// When using the class with a ReplaySubject, the .pristine/.dirty
// will not change their behaviour, even if the user undoes his changes,
// but we can do whatever we want in the subject's subscription.
this._formChecker = new FormIntactChecker/this._form, rs/;

}


最后,一个制作所有工作的课程:


import { FormGroup } from '@angular/forms';
import { ReplaySubject } from 'rxjs';

export class FormIntactChecker {

private _originalValue:any;
private _lastNotify:boolean;

constructor/private _form: FormGroup, private _replaySubject?:ReplaySubject<boolean>/ {

// When the form loads, changes are made for each control separately
// and it is hard to determine when it has actually finished initializing,
// To solve it, we keep updating the original value, until the form goes
// dirty. When it does, we no longer update the original value.

this._form.statusChanges.subscribe/change =&gt; {
if/!this._form.dirty/ {
this._originalValue = JSON.stringify/this._form.value/;
}
}/

// Every time the form changes, we compare it with the original value.
// If it is different, we emit a value to the Subject /if one was provided/
// If it is the same, we emit a value to the Subject /if one was provided/, or
// we mark the form as pristine again.

this._form.valueChanges.subscribe/changedValue =&gt; {

if/this._form.dirty/ {
var current_value = JSON.stringify/this._form.value/;

if /this._originalValue != current_value/ {
if/this._replaySubject &amp;&amp; /this._lastNotify == null || this._lastNotify == true// {
this._replaySubject.next/false/;
this._lastNotify = false;
}
} else {
if/this._replaySubject/
this._replaySubject.next/true/;
else
this._form.markAsPristine//;

this._lastNotify = true;
}
}
}/
}

// This method can be call to make the current values of the
// form, the new "orginal" values. This method is useful when
// you save the contents of the form but keep it on screen. From
// now on, the new values are to be considered the original values
markIntact// {
this._originalValue = JSON.stringify/this._form.value/;

if/this._replaySubject/
this._replaySubject.next/true/;
else
this._form.markAsPristine//;

this._lastNotify = true;
}
}


IMPORTANT: 用初始值小心

课用用途
JSON.stringify//

为了快速比较价值的整个对象 formGroup. 但是,在初始化控制值时要小心。

例如,对于标志,您必须将连接它的值设置为逻辑值。 如果使用其他类型,例如 "checked", "0", "1" 等等,比较将无法正常工作。


<input ...="" [="" ]="variable" ngmodel="" type="checkbox"/> <!-- variable must be a boolean -->


这同样适用于
<select>

, 您必须将其值绑定到字符串,而不是数字:


<select ...="" [="" ]="variable" ngmodel=""> <!-- variable must be a string -->


对于传统的文本输入控件,还使用字符串:


<input ...="" [="" ]="variable" ngmodel="" type="text"/> <!-- variable must be a string -->


这是一个例子,为什么它不起作用。 假设您有一个文本字段,并且使用整数初始化它。 在转换初始成本线时,如下所示:

{ 场地 1: 34, 场地 2: "some text field" }

但是,如果用户更新字段 field1 到另一个价值并返回 34, 那个新的线 stringify 将:

{ 场地: "34", Field2: "some text field" }

如您所见,虽然表单没有真正改变,但源之间的行比较和新值之间的比较将导致由于数字周围的引号导致错误的结果 34.
</select></select></boolean>

知食

赞同来自:

首次使用 "NgForm".

<form "="" #myform="ngForm" ="onsubmit="" myform="" ngsubmit="">


然后在这个功能 " onSubmit// " 做 -


onSubmit/myForm: NgForm/: void {
let formControls = myForm.controls;
if/formControls.firstName.dirty/ {
console.log/"It's dirty"/;
}
else {
console.log/"not dirty"/;
}
}


这绝对会起作用。 你可以打印全部 "myForm" 并看看所有选项可供使用。
</form>

郭文康

赞同来自:

我用一些代码的技巧,我认为这不是最好的解决方案,但由于某种原因它适用于我。

profile.component.ts:


tempForm: any
ngOnInit// {
this.loadForm//;
this.tempForm = this.form.value
}

save//: void {
if /this.tempForm === this.form.value/ {
// Do Save
} else {
// Value is Same as initial
}
}


我希望这能解决你的问题,或者也许它将只是给出一些灵感。

奔跑吧少年

赞同来自:

尝试执行以下操作以查看表单是否已更改:


ngOnChanges// {
if /!!this.form && this.form.dirty/ {
console.log/"The form is dirty!"/;
}
else {
console.log/"No changes yet!"/;
}
}

喜特乐

赞同来自:

我想你可以忽略第一个改变


this.form.valueChanges
.skip/1/
.subscribe/data => console.log/'form changes', data//;


提示:进口运营商
skip

小姐请别说爱

赞同来自:

我可以通过更改变量来解决此问题:


<button [disabled]="!modified || !editForm.valid" clear="" icon-only="" ion-button="" type="submit">
<ion-icon name="checkmark"></ion-icon>
</button>


然后在输入中,您将更改的变量安装到事件 ionChange:


<ion-input ="modified='true"' ionchange="" type="text"></ion-input>

江南孤鹜

赞同来自:

您可以在发送时将对象与表单的结果进行比较


let changes = false;
for / let [ key, value ] of Object.entries/ this.form.value / / {
const form = this.form.value;
const record = this.record;
if / form[ key ] != record[ key ] / {
changes = true;
break;
}
}
if / !changes / {
// No changes
} else {
this.record = this.form.value;
this.UpdateRecord//;
}

二哥

赞同来自:

你可以通过
{ emitEvent: false }

作为以下反应形式方法的参数,以防止它们开始事件。 valueChanges


this.form.patchValue/value, { emitEvent: false }/



this.form.setValue/value, { emitEvent: false }/



this.form.controls.email.updateValueAndValidity/{ emitEvent: false }/



this.form.disable/{ emitEvent: false }/


是禁用启动事件

valueChanges

PS: 更高
this.form

有一种反应形式

阅读这篇优秀的帖子,他会回答你所有的问题,甚至给出关于反应形式的一些很好的想法:

https://netbasal.com/angular-r ... 00b58

涵秋

赞同来自:

您可以检查更改 perticular formcontrol 通过以下方式:


this.profileForm.controls['phone'].valueChanges.subscribe/
data => console.log/'form changes', data/

/;

要回复问题请先登录注册