Angular materialAutoComplete字段服务调用比

时间:2018-04-12 08:19:14

标签: angular debounce angular-material-5 mat-autocomplete

this.filteredContact = this.contactControl.valueChanges.pipe(
  startWith(''),
  debounceTime(200),
  map(val => this.filterContact(val))
);

filterContact(val: string): any {
  if (val.length > 2) {
    return _.filter(
      this.contacts,
      item => item.name.toLowerCase().indexOf(val.toLowerCase()) !== -1
    );
  }
}

this.filteredContact = this.contactControl.valueChanges.pipe(
  startWith(''),
  debounceTime(200),
  switchMap(
    val =>
    val.length > 2 ?
    _.filter(
      this.contacts,
      item => item.name.toLowerCase().indexOf(val.toLowerCase()) !== -1
    ) :
    Observable.of([])
  ),
  map(result => result.contacts)
);

我正在使用Angular materialAutoComplete字段,其中服务调用在用户键入时拉取数据。由于用户输入的速度比服务提取数据的速度快,因此autocompleteSelection面板中实际显示的内容没有同步。如何在materialAutoComplete中实现完美的数据。如何匹配/克服用户在现场绑定的速度以及从服务中获取的输出以显示在autocompletePanel中?

public filteredCustomersByName: Observable<e.ICustomer[]>;

    this.filteredCustomersByName = this.customerNameControl.valueChanges.pipe(
      startWith(''),
      debounceTime(200),
      map(val => this.filterCustomersByName(val))
    );


  filterCustomersByName(val: string): any {
    if (val.length > 2) {
      this.appData.get(this.appData.url.getCustomerByName, [val]).subscribe(
        result => {
          this.customersByName = result.customers;
        },
        err => {
          console.log('Error ' + err.message);
          this.toastr.error(err.message);
        }
      );
      return this.customersByName;
    }
  }
            <div class="box-row">
              <mat-form-field>
                <input placeholder="Customer Name" type="text" #customerNameId matInput [formControl]="customerNameControl" [(ngModel)]='selectedCustomerName'
                  [matAutocomplete]="customerName" required>
                <mat-autocomplete #customerName="matAutocomplete" class='customerDetails'>
                  <mat-option (click)="setCustomerDetails(customer)" *ngFor="let customer of filteredCustomersByName | async" [value]="customer.name">
                    {{ customer.name}}
                  </mat-option>
                </mat-autocomplete>
              </mat-form-field>
            </div>

提前致谢。

 filterCustomerByCode(val: string): any {
    if (val.length > 2) {
      if (val.charAt(0).toLowerCase() !== 'b') {
        val = ('000000000000' + val).substr(-10);
      }
      this.appData.get(this.appData.url.getCustomerByCode, [val]).subscribe(
        result => {
          this.customersByCode = result.customers;
        },
        err => {
          console.log('Error ' + err.message);
          this.toastr.error(err.message);
        }
      );
      return this.customersByCode;
    }
  }

我尝试使用switchMap更改filteredContact,请检查并告诉我为什么在语句映射中的result.contacts中出现错误(result =&gt; result.contacts)

1 个答案:

答案 0 :(得分:1)

尝试使用switchMap。它将确保结果始终是新鲜的。

  

在每次发射时,前一个内部observable(你提供的函数的结果)被取消,新的observable被订阅

<强> filteredCustomersByName

this.filteredCustomersByName = this.customerNameControl.valueChanges.pipe(
  startWith(''),
  debounceTime(200),
  switchMap(val => val.length > 2 
      ? this.appData.get(this.appData.url.getCustomerByName, [val])
      : of([])
 ),
  map(result => result.customers)
);

<强> filterCustomerByCode

this.filterCustomerByCode = this.customerNameControl.valueChanges.pipe(
  startWith(''),
  debounceTime(200),
  switchMap((val: string) => {
    if (val.length > 2 || val.charAt(0).toLowerCase() === 'b') {
      const mappedVal = ('000000000000' + val).substr(-10);
      return this.appData.get(this.appData.url.getCustomerByName, [mappedVal]);
    }
    return of([]);
  }),
  map(result => result.customers)
);