Post 来自多个范围输入的值在 Angular 6 中随 debounceTime 发生变化

Post values from multiple range inputs on change in Angular 6 with debounceTime

在我的 Angular 6 项目中,我有一个包含 3 个范围输入和 1 个复选框的组件。 使用复选框,我可以 link 3 个范围输入中的 2 个的值,这样如果一个被更改,另一个也会相应地更改。 当复选框未选中时,第二个不会更新。 当其中一个范围输入发生变化时,所有 3 个控件的值都必须发送到 API.

到目前为止我是成功的。 问题是,当我更改范围输入时,会有 post 对 API 的突发请求。 我想减少请求的爆发。

在模板中我有以下控件:

<input class="my-custom-range" type="range" [min]="-1 * navControl.engine1.power.max" [max]="navControl.engine1.power.max" [(ngModel)]="controls.throttle1" (ngModelChange)="onChangeThrothel1($event)" [disabled]="!navControl.engine1.isOnline" >
<input class="my-custom-range" type="range" [min]="-1 * navControl.engine2.power.max" [max]="navControl.engine2.power.max" [(ngModel)]="controls.throttle2" (ngModelChange)="onChangeThrothel2($event)" [disabled]="!navControl.engine2.isOnline" >
<mat-slider min="-80" max="80" step="8" thumbLabel="true" vertical="true" [(ngModel)]="controls.mainHelm" (ngModelChange)="changeMainHelm($event)" [disabled]="!navControl.engine1.isOnline" style="margin-top: 4em; height: 100%"></mat-slider>
<mat-checkbox [(ngModel)]="syncEngines">Motor Sync</mat-checkbox>

我有一些接口是这样的:

export interface INavigationRequest {
  engine1: IEngineRequest;
  engine2: IEngineRequest;
}
export interface IEngineRequest {
  id: number;
  requestedPower: number;
  isForwardPropultion: boolean;
  requestedAngle: number;
  correctionPower: number;
  correctionAngle: number;
}

在 server.service.ts 我有以下内容:

updateEngines(params: INavigationRequest): Observable<INavigationResponse> {
  console.log('update engines', params);
  return this.http.post<INavigationResponse>(`${this.baseUrl}/api/navigation/post/`, params);
}

在 component.ts 我有以下内容:

public onChangeThrothel1(value): void {
  if (value && this.syncEngines) {
    this.controls.throttle2 = value;
  }
  console.log('1', this.controls.throttle1);
  console.log('2', this.controls.throttle2);
  this.updateNavControl();
}

public onChangeThrothel2(value): void {
  if (value && this.syncEngines) {
    this.controls.throttle1 = value;
  }
  console.log('1', this.controls.throttle1);
  console.log('2', this.controls.throttle2);
  this.updateNavControl();
}

public changeMainHelm(value): void {
  if (value) {
    this.controls.helm = value;
    this.updateNavControl();
  }
}

public updateNavControl(): void {
  let params: INavigationRequest = {
    engine1: {
      id: this.navControl.engine1.id,
      isForwardPropultion: this.navControl.engine1.isForwardPropultion,
      requestedPower: this.controls.throttle1,
      requestedAngle: this.controls.helm,
      correctionPower: this.navControl.engine1.power.correction,
      correctionAngle: this.navControl.engine1.angle.correction
    },
    engine2: {
      id: this.navControl.engine2.id,
      isForwardPropultion: this.navControl.engine2.isForwardPropultion,
      requestedPower: this.controls.throttle2,
      requestedAngle: this.controls.helm,
      correctionPower: this.navControl.engine2.power.correction,
      correctionAngle: this.navControl.engine2.angle.correction
    }
  };
  console.log(params);
  this.server.updateEngines(params).pipe(debounceTime(500), distinctUntilChanged()).subscribe(result => {
    console.log('HttpClient [POST] /api/navigation/post', result);
    this.procesEngines(result);
  }, error => {
    console.log(`There was an issue. ${error._body}.`);
  });
}

debounceTime 不起作用,所有更改都已提交。

我觉得debounce时间的位置不太对。 也许我的做法是完全错误的。

您必须将所有更改放在单个可观察对象上,然后您可以进行去抖动等操作。

你可以这样做:

private updateQueue = new Subject();
private updateQueueSubscription = null;

ngOnInit() {
    this.updateQueueSubscription = this.updateQueue
        .pipe(
            debounceTime(500),
            distinctUntilChanged(isEqual), // from lodash
            mergeMap(params => this.server.updateEngines(params))
        )
        .subscribe(
            (result) => {
                console.log('HttpClient [POST] /api/navigation/post', result);
                this.procesEngines(result);
            },
            error => {
                console.log(`There was an issue. ${error._body}.`);
            },
        )
}

ngOnDestroy() {
    this.updateQueueSubscription.unsubscribe();
}

public updateNavControl(): void {
    let params: INavigationRequest = {
        engine1: {
            id: this.navControl.engine1.id,
            isForwardPropultion: this.navControl.engine1.isForwardPropultion,
            requestedPower: this.controls.throttle1,
            requestedAngle: this.controls.helm,
            correctionPower: this.navControl.engine1.power.correction,
            correctionAngle: this.navControl.engine1.angle.correction
        },
        engine2: {
            id: this.navControl.engine2.id,
            isForwardPropultion: this.navControl.engine2.isForwardPropultion,
            requestedPower: this.controls.throttle2,
            requestedAngle: this.controls.helm,
            correctionPower: this.navControl.engine2.power.correction,
            correctionAngle: this.navControl.engine2.angle.correction
        }
    };
    console.log(params);
    this.updateQueue.next(params);
}

updateQueue 将是一个主题,您可以在其中发送所有更改,您可以对它们进行反跳并使用 distinctUntilChanged

另请注意:您的代码中的 distinctUntilChanged 将不起作用,因为它不会进行深入比较 - 为此,您将需要例如来自 Lodash 的 isEqual 函数。