我有这样的 Angular 代码,它监听多个字段的更改,然后在其中任何一个字段发生更改时保存更改。问题是,即使控制台没有记录任何内容,故事也会被保存,这意味着不应该触发任何可观察对象。为什么保存被调用以及如何调试它?
merge([
this.form.get('storyName').valueChanges.pipe(tap(x => console.log('storyName', x))),
this.form.get('storyTypeId').valueChanges.pipe(tap(x => console.log('storyTypeId', x))),
this.form.get('backlogId').valueChanges.pipe(tap(x => console.log('backlogId', x))),
this.form.get('ownerUserId').valueChanges.pipe(tap(x => console.log('ownerUserId', x))),
this.form.get('points').valueChanges.pipe(tap(x => console.log('points', x))),
this.form.get('tags').valueChanges.pipe(tap(x => console.log('tags', x))),
]).pipe(
debounceTime(300),
).subscribe(async () => {
try {
await this.saveStory();
} finally {
this.isSavingStory = false;
}
});
尝试删除数组,而只需将
valueChanges
作为参数传递给 merge
!
...
merge(
this.form
.get('input')!
.valueChanges.pipe(tap((x) => console.log('input', x))),
this.form
.get('select')!
.valueChanges.pipe(tap((x) => console.log('select', x))),
this.form
.get('textarea')!
.valueChanges.pipe(tap((x) => console.log('textarea', x)))
)
...
import { Component } from '@angular/core';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { FormGroup, ReactiveFormsModule, FormControl } from '@angular/forms';
import { tap, debounceTime } from 'rxjs/operators';
import { merge } from 'rxjs';
/** @title Simple form field */
@Component({
selector: 'form-field-overview-example',
templateUrl: 'form-field-overview-example.html',
styleUrl: 'form-field-overview-example.css',
standalone: true,
imports: [
MatFormFieldModule,
MatInputModule,
MatSelectModule,
ReactiveFormsModule,
],
})
export class FormFieldOverviewExample {
isSavingStory = false;
form = new FormGroup({
input: new FormControl(''),
select: new FormControl(''),
textarea: new FormControl(''),
});
ngOnInit() {
merge(
this.form
.get('input')!
.valueChanges.pipe(tap((x) => console.log('input', x))),
this.form
.get('select')!
.valueChanges.pipe(tap((x) => console.log('select', x))),
this.form
.get('textarea')!
.valueChanges.pipe(tap((x) => console.log('textarea', x)))
)
.pipe(debounceTime(300))
.subscribe(() => {
try {
console.log('saveStory');
} finally {
this.isSavingStory = false;
}
});
}
}
<form [formGroup]="form"> <mat-form-field>
<mat-label>Input</mat-label>
<input matInput formControlName="input" /> </mat-form-field> <mat-form-field>
<mat-label>Select</mat-label>
<mat-select formControlName="select">
<mat-option value="one">First option</mat-option>
<mat-option value="two">Second option</mat-option>
</mat-select> </mat-form-field> <mat-form-field>
<mat-label>Textarea</mat-label>
<textarea matInput formControlName="textarea"></textarea> </mat-form-field> </form>
如果认为代码中唯一的问题是您将数组传递给合并运算符,而不是一个接一个地声明内部可观察值:
我相信这应该有效:
merge(
this.form.get('storyName').valueChanges.pipe(tap(x => console.log('storyName', x))),
this.form.get('storyTypeId').valueChanges.pipe(tap(x => console.log('storyTypeId', x))),
this.form.get('backlogId').valueChanges.pipe(tap(x => console.log('backlogId', x))),
this.form.get('ownerUserId').valueChanges.pipe(tap(x => console.log('ownerUserId', x))),
this.form.get('points').valueChanges.pipe(tap(x => console.log('points', x))),
this.form.get('tags').valueChanges.pipe(tap(x => console.log('tags', x))),
).pipe(
debounceTime(300),
).subscribe(async () => {
try {
await this.saveStory();
} finally {
this.isSavingStory = false;
}
});
我还希望您给您一个提示,当尝试按名称访问包含的表单控件时,您可以使用 FormGroup 中的控件属性来获得良好的自动完成功能:
merge(
this.form.controls.storyName.valueChanges.pipe(tap(x => console.log('storyName', x))),
this.form.controls.storyTypeId.valueChanges.pipe(tap(x => console.log('storyTypeId', x))),
this.form.controls.backlogId.valueChanges.pipe(tap(x => console.log('backlogId', x))),
this.form.controls.ownerUserId.valueChanges.pipe(tap(x => console.log('ownerUserId', x))),
this.form.controls.points.valueChanges.pipe(tap(x => console.log('points', x))),
this.form.controls.tags.valueChanges.pipe(tap(x => console.log('tags', x))),
).pipe(
debounceTime(300),
).subscribe(async () => {
try {
await this.saveStory();
} finally {
this.isSavingStory = false;
}
});
希望这有帮助!