如何消除Angular中的键盘输入(keyUp)的反跳并诱导主题/可观察对象

时间:2019-03-12 14:43:03

标签: javascript angular rxjs angular2-observables

正如我之前提到的,我是angular的新手,我现在正在尝试自学编码。我正在为自己制作一个应涵盖“现实世界”场景的应用程序。我目前正在尝试以某种形式使用材料自动完成功能,以便当用户向输入中添加/插入一个值时,keyup事件调用一种方法,该方法进行API调用并返回一些数据,然后使用该方法来填充自动完成功能(我的页面中有3个)。我的作品有用,但是a)感觉效率很低b)并非最佳实现(或Angular方式和c),它缺少去抖动功能,以防止用户使用API​​调用使服务器超载。

在这里,我从HTML模板中获取带有3个输入的表单,每个表单都有一个捕获keyup事件的方法。每个输入都分配有一个垫自动完成功能,该自动迭代功能通过与用户输入匹配的值进行迭代(因此,如果用户在公司输入值(例如“ Cola Inc”,“ Columbia University”,“ Color Clothing Inc”)中输入“ Col”,则

<form novalidate [formGroup]="assignmentForm">
  <div>
    <input type="text" matInput placeholder="User" formControlName="worker" name="worker" (keyup)="getTags($event)" [matAutocomplete]="workerTemplate">
    <mat-autocomplete #workerTemplate="matAutocomplete">
      <mat-option *ngFor="let worker of workerTags" [value]="worker">{{ worker.displayName}}</mat-option>
    </mat-autocomplete>
  </div>

  <div>
    <input type="text" matInput placeholder="Company" formControlName="company" name="company" (keyup)="getTags($event)" [matAutocomplete]="companyTemplate">
    <mat-autocomplete #companyTemplate="matAutocomplete">
      <mat-option *ngFor="let company of companyTags" [value]="company">{{company.displayName}}</mat-option>
    </mat-autocomplete>
  </div>

  <div>
    <input type="text" matInput placeholder="Department" formControlName="department" name="department" (keyup)="getTags($event)" [matAutocomplete]="departmentTemplate">
    <mat-autocomplete #departmentTemplate="matAutocomplete">
      <mat-option *ngFor="let department of departmentTags" [value]="department">{{department.displayName}}</mat-option>
    </mat-autocomplete>
  </div>
</form>

此方法需要用户输入并调用API,然后填充正确的mat-option数组(为了便于阅读,我减少了很多组件代码)

        public companyTags: any[];
        public departmentTags: any[];
        public workerTags: any[];

        constructor(private apiService: ApiService) {}

        public getTags(ev: KeyboardEvent): void {
        // if the user presses backspace the value is "" and all results are returned (to set limit)
        if((<HTMLInputElement>ev.target).value !== '') {
    // the api method takes 3 args type, value and limit, it returns an object array         
    this.apiService.getTags((<HTMLInputElement>ev.target).name, (<HTMLInputElement>ev.target).value, 3).subscribe((res) => {
            this.clearAllTags();
            // as the target name is used in the tag array name we can use interpolation
            // rather than a horrible if then else
            this[`${(<HTMLInputElement>ev.target).name}Tags`] = res;
          });
        } else {
          this.clearAllTags();
        }
      }

      /**
       * Clear all specific Tag Arrays
       */
      public clearAllTags(): void {
        this.companyTags = null;
        this.departmentTags = null;
        this.workerTags = null;
      }

我想知道以下几点:首先,我可以一次使用自动完成功能,还是在三个输入之间共享它,因为我一次只显示一个自动完成功能,从而使表格更加简化?其次,我如何在这里使用或引入反跳?我应该使用RxJS和Observables,如果应该使用3个Observables,还是可以使用一个Observable监听/订阅所有三个输入?我已经对此进行了一些阅读,但我有些困惑。

如果我的问题措辞不好,请声明,我将重写我的问题。我想以最好的方式学习Angular。非常感谢您抽出宝贵的时间来帮助我。

0 个答案:

没有答案