0

我正在尝试使用 Angular 5 Material 的自动完成功能创建一个客户(或任何东西)的下拉列表。但与 Angular 网站上提供的示例不同,我的数据不是静态的,而是在数据调用之后返回的getAllCustomer()

我遇到的问题似乎是filterOptions在数据从我的getAllCustomer()方法返回之前分配。

如何确保仅filterOptions在我的数据返回后分配我的?

这是我的代码:

filteredOptions: Observable<string[]>;

constructor(private loadDataService: LoadDataService, private assetDataService: AssetDataService, private router: Router, private toastr: ToastrService) { }

ngOnInit() {
    this.getAllCustomers();
    this.filteredOptions = this.myCustomerSearchControl.valueChanges.pipe(
      startWith(''),
      map(val => this.filter(val))
    );
}

filter(val: string): string[] {
    return this.customerArray.filter(option => option.toLowerCase().indexOf(val.toLowerCase()) === 0);
}

getAllCustomers() {
    this.loadDataService.getAllCustomers()
    .subscribe(data => {
      this.customerArray = data;
    });
}

这是我的 HTML:

<mat-form-field>
    <input type="text" placeholder="Customer Search" aria-label="Number" matInput [formControl]="myCustomerSearchControl" [matAutocomplete]="auto">
        <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
            <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
            {{ option }}
        </mat-option>
    </mat-autocomplete>
</mat-form-field>

作为奖励,我如何能够实现相同的功能,但使用实际的搜索功能返回用户在搜索框中键入的数据 - 即按字符串方法搜索?

这是我的searchByString功能:

searchForCustomerByString(string) {
    this.loadDataService.getCustomer(string)
      .subscribe(data => {
        this.returnedCustomers = data;
      });
}
4

2 回答 2

0

对此更好、更清洁的解决方案是使用冷可观察对象。

filteredOptions: Observable<string[]>;
customers: Observable<string[]>; // -> assuming the type here, bc your code doesn't provide the customerArray type

constructor(private loadDataService: LoadDataService, private assetDataService: AssetDataService, private router: Router, private toastr: ToastrService) { }

ngOnInit() {
    this.customers = this.loadDataService.getAllCustomers();
    this.filteredOptions = Observable.combineLatest(
       this.customers,
       this.myCustomerSearchControl.valueChanges.startWith(null)
    ).map(([customers, filter]) => {
      if(!customers || customers.length === 0) {
          return [];
      }

      if (!filter || filter === '') {
         return customers;
      }

       return customers.filter(.....); // apply your filter.
    })
}

无需在组件销毁时存储和取消订阅的直接订阅。

于 2018-03-08T07:42:39.237 回答
0

您可以像这样在订阅结果中定义变量:

getAllCustomers() {
    this.loadDataService.getAllCustomers()
    .subscribe(data => {
      this.customerArray = data;
      this.filteredOptions = this.myCustomerSearchControl.valueChanges.pipe(
          startWith(''),
          map(val => this.filter(val))
      );
    });
}

但是变量filteredOptions可能没有被初始化,所以也许你可以使用像BehaviorSubject这样的东西来初始化变量。

于 2018-03-08T07:13:36.197 回答