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
您的搜索逻辑如下:
- 如果名字 或 姓氏等于 "legend",return true
- 如果名字 或 姓氏等于 "marshall",return true
- 如果名字 或 姓氏等于 "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;
}
});
}
我正在我的应用程序中使用 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
您的搜索逻辑如下:
- 如果名字 或 姓氏等于 "legend",return true
- 如果名字 或 姓氏等于 "marshall",return true
- 如果名字 或 姓氏等于 "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;
}
});
}