Ionic4:搜索栏结果未按预期工作

Ionic4: searchbar results not working as expected

我正在我的应用程序中使用 ion-searchbar。我使用搜索栏按名字 and/or 姓氏过滤客户列表,但我真的很难解决这两个问题:

问题 1: 搜索栏仅匹配名字或姓氏,但不能同时匹配两者。例如:如果我是客户并且我的名字是 Marshall Legend 并且我输入 Marshall 过滤器将起作用或者如果我输入 Legend 过滤器将起作用,但是如果我输入 Marshall Legend 我找不到匹配项。

问题2:这个作为场景更容易解释。客户列表正确地过滤了列表并显示了正确的结果,例如当我在搜索栏中输入 "Marshall" 时,只有名为 "Marshall" 的人会显示。然而,然后一个新客户被添加到列表中(来自另一个客户)并且突然间所有客户都被显示并且过滤器被忽略,即使 "Marshall" 仍然在我的搜索栏中。

我在这两个问题上苦苦挣扎了很长时间,非常感谢任何帮助。下面是我的代码:

我的组件代码

export class Tab2Page implements OnInit {
  public searchTerm: string = "";
  public customerCollection: AngularFirestoreCollection<any>;
  public customers: any[];
  public unfilteredCustomers: any[];

  constructor(private afs: AngularFirestore, 
    public modalController: ModalController,
    private databaseService: DatabaseService) {}

  ngOnInit(){
    this.customerCollection = this.afs.collection('Customers');
    this.customerCollection.valueChanges().subscribe( val => {
      this.customers = val;
      this.unfilteredCustomers = val;
    });
  }

  /**
   * Search functionality 
   */
  public onSearchTerm() {
    if(/\S/.test(this.searchTerm)){
      this.customers = this.unfilteredCustomers.filter(customer => {
        return customer.lastName.toLowerCase().includes(this.searchTerm.toLowerCase())  
        || customer.firstName.toLowerCase().includes(this.searchTerm.toLowerCase());
      });
    } else {
      this.customers = this.unfilteredCustomers;
    }
  }

我的模板代码

    <ion-item-sliding *ngFor="let customer of customers">
          <ion-item-options side="start">
            <ion-item-option (click)="viewCustomerDetails(customer)">Details</ion-item-option>
          </ion-item-options>
        <ion-item>
         <ion-label>
         <ion-icon name="person"></ion-icon> {{customer?.firstName}} 
           {{customer?.lastName}}
         </ion-label>
         </ion-item>
          <ion-item-options side="end">
            <ion-item-option color="danger" (click)="removeCustomer(customer)">Return</ion-item-option>
          </ion-item-options>
    </ion-item-sliding>

你可以这样使用

public onSearchTerm() {
if(/\S/.test(this.searchTerm)){
  this.customers = this.unfilteredCustomers.filter(customer => {
    let fullname = customer.firstName+" "+customer.lastName
    return fullname.toLowerCase().includes(this.searchTerm.toLowerCase())  ;
  });
} else {
  this.customers = this.unfilteredCustomers;
}

}

这将 return 匹配名字或姓氏而不是两者

return customer.lastName.toLowerCase().includes(this.searchTerm.toLowerCase())  
    || customer.firstName.toLowerCase().includes(this.searchTerm.toLowerCase());

问题 1

您的搜索逻辑如下:

  1. 如果名字 姓氏等于 "legend",return true
  2. 如果名字 姓氏等于 "marshall",return true
  3. 如果名字 姓氏等于 "marshall legend",return true

由于名字和姓氏在 Firestore 中分为两个属性,因此第三种情况永远不会发生。试试这个:

  public onSearchTerm() {
    if (searchTerms.length < 1) {
      this.customers = this.unfilteredCustomers;
      return;
    }

    const searchTerms = this.searchTerm.split(' ').map(s => s.trim().toLowerCase());

    this.customers = this.unfilteredCustomers.filter(customer => {
      var firstName = customer.firstName.toLowerCase();
      var lastName = customer.lastName.toLowerCase();

      var results = searchTerms.filter(name => firstName.includes(name) || lastName.includes(name));

      return results.length > 0;
    });

  }

问题2

在您的 ngOnInit 函数中,您订阅了您的客户集合以监视任何更改,当发生这种情况时,它会覆盖您的 this.customers 变量。这就是您的列表刷新显示所有结果的原因。试试这个:

  ngOnInit(){
    this.customerCollection = this.afs.collection('Customers');
    this.customerCollection.valueChanges().subscribe( val => {
      this.unfilteredCustomers = val;

      // If there is a search term, filter the results
      if (this.searchTerm.trim().length > 0) {
        this.onSearchTerm();
      } else {
        this.customers = val;   
      }
    });
  }