Angular 2 表单 valueChanges 连续触发
Angular 2 form valueChanges fires continuously
我正在尝试使用从服务中获得的值更新表单的值 name,一旦 location 字段为填充。我通过观察表单对象的 valueChanges 来尝试做到这一点。它可以工作,但它会持续触发,尽管值不再改变。 debounceTime() 和 distinctUntilChanged() 没有影响:
bookmarkForm: FormGroup;
ngOnInit(): void {
this.bookmarkForm = this.formBuilder.group({
name: ['', Validators.required],
location: ['', Validators.required],
description:'',
shared: false
});
this.bookmarkForm.valueChanges
//.debounceTime(800)
//.distinctUntilChanged()
.subscribe(formData => {
if(formData.location){
console.log('location changed', formData);
this.bookmarkService.getBookmarkTitle(formData.location).subscribe(response => {
console.log('Response: ', response);
if(response){
this.bookmarkForm.patchValue({name:response.title}, {emitEvent: false});
}
});
}
});
}
html 模板
<div class="container">
<div class="col-md-8 col-md-offset-2">
<form [formGroup]="bookmarkForm" novalidate (ngSubmit)="saveBookmark(bookmarkForm.value, bookmarkForm.valid)">
<div class="form-group">
<label for="location">Location*</label>
<input type="text" class="form-control" id="location"
required
name="location"
formControlName="location"
placeholder="Usually an URL">
<div [hidden]="bookmarkForm.controls.location.valid || (bookmarkForm.controls.location.pristine && !submitted)"
class="alert alert-danger">
Location is required
</div>
</div>
<div class="form-group">
<label for="name">Name*</label>
<input type="text" class="form-control" id="name"
required
formControlName="name"
placeholder="Name of the bookmark to recognize later">
<div [hidden]="bookmarkForm.controls.name.valid || (bookmarkForm.controls.name.pristine && !submitted)"
class="alert alert-danger">
Name is required
</div>
</div>
<div class="form-group">
<label for="description">Notes...</label>
<textarea class="form-control"
id="description"
formControlName="description"
placeholder="Make some notes to help you later by searching...">
</textarea>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="true" formControlName="shared">
<strong> Make this bookmark public so others can benefit from it </strong>
</label>
</div>
<button type="submit" class="btn btn-default" [disabled]="!bookmarkForm.valid">Submit</button>
</form>
</div>
</div>
有什么想法吗?谢谢
但是在这个订阅中你正在修补值,为什么?
this.bookmarkForm.valueChanges
.subscribe(formData => {
if(formData.location){
console.log('location changed', formData);
this.bookmarkService.getBookmarkTitle(formData.location).subscribe(response => {
console.log('Response: ', response);
if(response){
this.bookmarkForm.patchValue({name:response.title}); <----- THIS HERE
}
});
}
});
您因此遇到问题
this.bookmarkForm.patchValue({name:response.title});
您设置了 emitEvent: false 选项以防止表单触发 valueChanges:
form.patchValue({name:response.title}, {emitEvent: false})
谢谢你给我指明了正确的方向。我必须在 FormControl 上使用 emitEvent 标志执行 patchValue。 FormGroup 上的 patchValue 不采用此标志。所以这是我的解决方案:
this.bookmarkForm.valueChanges
.debounceTime(800)
.distinctUntilChanged()
.subscribe(formData => {
if(formData.location){
console.log('location changed', formData);
this.bookmarkService.getBookmarkTitle(formData.location).subscribe(response => {
console.log('Respoonse: ', response);
if(response){
this.bookmarkForm.controls['name'].patchValue(response.title, {emitEvent : false});
}
});
}
});
现在更优雅的方法是仅在 location 字段中监听变化,然后才填写 title:
this.bookmarkForm.controls['location'].valueChanges
.debounceTime(800)
.distinctUntilChanged()
.subscribe(location => {
console.log('Location: ', location);
this.bookmarkService.getBookmarkTitle(location).subscribe(response => {
if(response){
this.bookmarkForm.controls['name'].patchValue(response.title, {emitEvent : false});
}
});
});
我正在尝试使用从服务中获得的值更新表单的值 name,一旦 location 字段为填充。我通过观察表单对象的 valueChanges 来尝试做到这一点。它可以工作,但它会持续触发,尽管值不再改变。 debounceTime() 和 distinctUntilChanged() 没有影响:
bookmarkForm: FormGroup;
ngOnInit(): void {
this.bookmarkForm = this.formBuilder.group({
name: ['', Validators.required],
location: ['', Validators.required],
description:'',
shared: false
});
this.bookmarkForm.valueChanges
//.debounceTime(800)
//.distinctUntilChanged()
.subscribe(formData => {
if(formData.location){
console.log('location changed', formData);
this.bookmarkService.getBookmarkTitle(formData.location).subscribe(response => {
console.log('Response: ', response);
if(response){
this.bookmarkForm.patchValue({name:response.title}, {emitEvent: false});
}
});
}
});
}
html 模板
<div class="container">
<div class="col-md-8 col-md-offset-2">
<form [formGroup]="bookmarkForm" novalidate (ngSubmit)="saveBookmark(bookmarkForm.value, bookmarkForm.valid)">
<div class="form-group">
<label for="location">Location*</label>
<input type="text" class="form-control" id="location"
required
name="location"
formControlName="location"
placeholder="Usually an URL">
<div [hidden]="bookmarkForm.controls.location.valid || (bookmarkForm.controls.location.pristine && !submitted)"
class="alert alert-danger">
Location is required
</div>
</div>
<div class="form-group">
<label for="name">Name*</label>
<input type="text" class="form-control" id="name"
required
formControlName="name"
placeholder="Name of the bookmark to recognize later">
<div [hidden]="bookmarkForm.controls.name.valid || (bookmarkForm.controls.name.pristine && !submitted)"
class="alert alert-danger">
Name is required
</div>
</div>
<div class="form-group">
<label for="description">Notes...</label>
<textarea class="form-control"
id="description"
formControlName="description"
placeholder="Make some notes to help you later by searching...">
</textarea>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" value="true" formControlName="shared">
<strong> Make this bookmark public so others can benefit from it </strong>
</label>
</div>
<button type="submit" class="btn btn-default" [disabled]="!bookmarkForm.valid">Submit</button>
</form>
</div>
</div>
有什么想法吗?谢谢
但是在这个订阅中你正在修补值,为什么?
this.bookmarkForm.valueChanges
.subscribe(formData => {
if(formData.location){
console.log('location changed', formData);
this.bookmarkService.getBookmarkTitle(formData.location).subscribe(response => {
console.log('Response: ', response);
if(response){
this.bookmarkForm.patchValue({name:response.title}); <----- THIS HERE
}
});
}
});
您因此遇到问题
this.bookmarkForm.patchValue({name:response.title});
您设置了 emitEvent: false 选项以防止表单触发 valueChanges:
form.patchValue({name:response.title}, {emitEvent: false})
谢谢你给我指明了正确的方向。我必须在 FormControl 上使用 emitEvent 标志执行 patchValue。 FormGroup 上的 patchValue 不采用此标志。所以这是我的解决方案:
this.bookmarkForm.valueChanges
.debounceTime(800)
.distinctUntilChanged()
.subscribe(formData => {
if(formData.location){
console.log('location changed', formData);
this.bookmarkService.getBookmarkTitle(formData.location).subscribe(response => {
console.log('Respoonse: ', response);
if(response){
this.bookmarkForm.controls['name'].patchValue(response.title, {emitEvent : false});
}
});
}
});
现在更优雅的方法是仅在 location 字段中监听变化,然后才填写 title:
this.bookmarkForm.controls['location'].valueChanges
.debounceTime(800)
.distinctUntilChanged()
.subscribe(location => {
console.log('Location: ', location);
this.bookmarkService.getBookmarkTitle(location).subscribe(response => {
if(response){
this.bookmarkForm.controls['name'].patchValue(response.title, {emitEvent : false});
}
});
});