Mat-slide:一次更改触发价值更改的两倍订阅

时间:2019-03-17 09:11:05

标签: angular angular-material

我想将滑块与输入文本同步。工作正常。另外,我还希望控件在发生模糊事件时进行更新(updateon: 'blur',但是我还希望在滑动条更改时立即更新formcontrol的值。

https://stackblitz.com/edit/angular-cakpgs

现在,我的问题是:当我通过滑动条更改控件的值时,会触发两次表单的值更改。更改值时,我在公式器中执行patchValue,因为我想立即更新值。并且当滑块失去焦点(模糊事件)时,将再次触发valuechanges通知。

我该怎么做,仅触发一次我的配方器的值更改,并要求:

  1. 在发生模糊事件updateon: 'blur'
  2. 时,应更新formcontrol
  3. 通过滑动条更改的值应立即更新

2 个答案:

答案 0 :(得分:0)

如果已经有了formControls,则无需执行[value]="AgeControl.value",仅通过formControl来更新值...因为我们要检测每个输入(类型:滑块或文本)的变化,然后复制,我们为所有输入添加了(change)

为了使更新更加迅速,我在表单的底部添加了第三个输入,该输入在每次击键时进行了这些更改,使用<input />进行更新会更加有趣。希望这就是您想要的。

在您的existing stackblitz中,将您的 hello-component.ts 设置为:

import { Component, OnInit, OnChanges } from '@angular/core';
// Must import to use Forms functionality  
import { FormBuilder, FormGroup, Validators, FormsModule, NgForm, FormControl } from '@angular/forms';

@Component({
  selector: 'app-hello-component',
  templateUrl: './hello-component.component.html',
  styleUrls: ['./hello-component.component.css']
})
export class HelloComponentComponent implements OnInit, OnChanges {

  form: FormGroup;

  constructor(private fb: FormBuilder) {
    // To initialize FormGroup  
    this.form = fb.group({
      'age': [null, { updateOn: 'blur' }]
    });
    this.form.valueChanges.subscribe(change => console.log(change));
  }

  ngOnInit() {
    this.AgeControl.setValue(10);
  }
  ngOnChanges() {
    console.log('change triggered');
  }

  public get AgeControl(): FormControl {
    return this.form.get('age') as FormControl;
  }
  onInputChange(event: any) {
    //value must change immediately
    this.form.patchValue({ 'age': event.target.value });
  }
  onSliderChange(event: any) {
    this.form.patchValue({ 'age': event.value });
  }
  onInputKeystroke(event: any) {
    this.form.patchValue({ 'age': event.target.value });
  }

}

在您的existing stackblitz中,将您的 hello-component.html 设置为:

<mat-slider thumbLabel tickInterval="1" min="1" [formControl]="AgeControl" (change)="onSliderChange($event)" max="100">
</mat-slider>
<br/>
<input [formControl]="AgeControl" (change)="onInputChange($event)">
<br/>
<input [formControl]="AgeControl" (change)="onInputChange($event)">
<pre>{{ form.value | json }}</pre>
<input [formControl]="AgeControl" (keyup)="onInputKeystroke($event)">

答案 1 :(得分:0)

我做了以下事情:

this.form.valueChanges
.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)))
.subscribe(change => console.log(change));

因此,我检查表单是否真的发生更改,如果发生更改,那么将执行订阅者。否则,不会呼叫订户。