物料自动完成加载数据的值随http调用而变化

时间:2018-01-19 13:17:24

标签: angular

在我的angular 4应用程序中,我在FormGroup中有一些材料自动完成,我只想在用户在自动完成字段中写入内容时搜索(进行HTTP调用)。 所以我遵循这个例子: stackblitz

但在我的情况下,我需要拨打远程电话来检索信息,因此我必须拨打电话:

Service.ts

  getCustomers(name: string) {


    return this.endPointUrlService.checkIfMapIsReady(this.entityLink[2])
      .flatMap((res) => {
        return this.http.get(this.endPointUrlService.cutLinks
          (this.endPointUrlService.mapNames.get('customersSearchMap').get('autocompleteWithWallet')), { params })
          .map((response) => <Customer[]>response);
      })
  }

正如您所看到的,我的服务返回了Customer[]

的可观察量

那么如何让它在组件中运行呢? 或者更一般地说,如何调整价值变化呢?

1 个答案:

答案 0 :(得分:1)

<强>组件:

import { FormControl } from '@angular/forms';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

customerControl = new FormControl();
matchingCustomers = new BehaviorSubject<string[]>([]);

ngOnInit() {
  this.customerControl.valueChanges.subscribe(val => {
    this.customerService.getCustomers(val).subscribe(customers => {

      this.matchingCustomers.next(customers);

      // OR (depends on where you want do filtering [component|service|server]):

      // this.matchingCustomers.next(customers.filter(customer => {
      //   return customer.toLowerCase().indexOf(val.toLowerCase()) > -1;
      // }));

    });
  });
}

<强>模板:

<mat-form-field>
    <input matInput [matAutocomplete]="auto" [formControl]="customerControl">
    <mat-autocomplete #auto="matAutocomplete">
        <mat-option *ngFor="let customer of matchingCustomers | async" [value]="customer">
            {{ customer }}
        </mat-option>
    </mat-autocomplete>
</mat-form-field>

服务中,我会做一些检查以防止冗余的HTTP调用。 像这样:

// optimizations possible

private lastSearchQuery: string = '';
private cachedCustomers: Customer[] = [];

getCustomers(name: string): Observable<Customer[]> {
  if (name.length > 2) { // developer defined value to prevent large responses
    // first search || 'name' is not part of 'lastSearchQuery'
    if (this.lastSearchQuery == ''
      || this.lastSearchQuery.toLowerCase().indexOf(name.toLowerCase()) === -1) {
      this.lastSearchQuery = name;
      return this.http.get<Customer[]>('https://example.org/customers?q=' + name).map(customers => {
        this.cachedCustomers = customers; 
        return customers;
      });
    } else { return Observable.of(this.cachedCustomers); }
  } else { return Observable.of([]); }
}