我已经阅读了SO,Github等上的filterPredicate的各种实现,但是它们对我了解如何处理预先输入搜索没有帮助。
我在输入表单字段中输入一个字母,例如p
,然后从数据库接收所有姓氏以p
开头的数据。我设置的那部分工作正常。但是,当我输入下一个字母r
时,我不想再次打入数据库。我想过滤数据表中以pr
开头的姓氏。这就是麻烦的开始。
当我键入第二个字母时,我有一个if / else语句,用于测试我正在使用的var字符串中是否包含> 1。完成后,我会将参数传递给一个函数,以使用已经从数据库下载的数据对表进行自定义过滤。我避免了每个字母都起作用的数据库调用。我不了解“((数据,过滤器)”)。它们看起来像参数,但不是。它们如何工作?完成该操作需要什么代码?
(我有`dataSource.filter = filterValue;在其他地方工作正常。)
Params解释:
column = user_name
filterValue = pr...
混乱:
public filterColumn(column: string, filterValue: string, dataSource) {
dataSource.filterPredicate = (data, filter) => {
console.log('data in filter column: ', data); // Never called.
// What goes here?
// return ???;
}
}
我的dataSource对象。我看到filterPredicate,数据和过滤器属性可以使用。而是抽象如何使用它们。
dataSource in filterColumn: MatTableDataSource {_renderData: BehaviorSubject, _filter: BehaviorSubject, _internalPageChanges: Subject, _renderChangesSubscription: Subscriber, sortingDataAccessor: ƒ, …}
filterPredicate: (data, filter) => {…}arguments: [Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
at Function.invokeGetter (<anonymous>:2:14)]caller: (...)length: 2name: ""__proto__: ƒ ()[[FunctionLocation]]: data-utilities.service.ts:43[[Scopes]]: Scopes[3]
filteredData: (3) [{…}, {…}, {…}]
sortData: (data, sort) => {…}
sortingDataAccessor: (data, sortHeaderId) => {…}
_data: BehaviorSubject {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}
_filter: BehaviorSubject {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}
_internalPageChanges: Subject {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}
_paginator: MatPaginator {_isInitialized: true, _pendingSubscribers: null, initialized: Observable, _disabled: false, _intl: MatPaginatorIntl, …}
_renderChangesSubscription: Subscriber {closed: false, _parentOrParents: null, _subscriptions: Array(1), syncErrorValue: null, syncErrorThrown: false, …}
_renderData: BehaviorSubject {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}data: (...)filter: (...)paginator: (...)sort: (...)__proto__: DataSource
答案 0 :(得分:0)
我已经包括了我在Angular中制作的大部分用于预搜索的组件。预先输入代码的内容位于底部的实用程序共享组件中。我在这里使用了共享组件,因为我将在许多地方使用它。但是,我认为这是一个hack,可能会有一个更优雅的答案。这很有效,很容易,但是还不是很漂亮。我现在没有更多的时间来弄清楚。我怀疑答案在RegEx中。
在.pipe的typeahead.compoent中,您将找到如何在实用程序中调用代码。
此代码在共享组件typeahead.component.ts
中 public searchLastName$ = new Subject<string>(); // Binds to the html text box element.
ngAfterViewInit() {
// -------- For Column Incremental Queries --------- //
// searchLastName$ binds to the html element.
this.searchLastName$.subscribe(result => {
this.queryLastName(result);
});
}
// --------- LAST NAME INCREMENTAL QUERY --------------- //
private queryLastName(filterValue) {
// Custom filter for this function. If in ngOnInit on the calling component then it applies
// to the whole calling component. We need various filters so that doesn't work.
this.membersComponent.dataSource.filterPredicate = (data: { last_name: string }, filterValue: string) =>
data.last_name.trim().toLowerCase().indexOf(filterValue) !== -1;
// When the first letter is typed then get data from db. After that just filter the table.
if (filterValue.length === 1) {
filterValue = filterValue.trim(); // Remove whitespace
// filterValue = filterValue.toUpperCase(); // MatTableDataSource defaults to lowercase matches
const lastNameSearch = gql`
query ($last_name: String!) {
lastNameSearch(last_name: $last_name) {
...membersTableFrag
}
}
${membersTableFrag}
`;
this.apollo
.watchQuery({
query: lastNameSearch,
variables: {
last_name: filterValue,
},
})
.valueChanges
.pipe(
map(returnedArray => {
// console.log('returnedArray in map: ', returnedArray); // All last_name's with the letter in them someplace.
const membersArray = returnedArray.data['lastNameSearch']; // extract items array from GraphQL JSON array
// For case insensitive search
const newArray = membersArray.filter(this.utilitiesService.filterBy(filterValue, 'last_name'));
return newArray;
})
)
.subscribe(result => {
this.membersComponent.dataSource.data = result;
});
} else {
// Filter the table instead of calling the db for each letter entered.
// Note: Apollo client doesn't seem able to query the cache with this kind of search.
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
// Interface and redefinition of filterPredicate in the ngOnInit
this.membersComponent.dataSource.filter = filterValue; // Filters all columns unless modifed by filterPredicate.
}
}
utilities.service.ts
// -------------- DATABASE COLUMN SEARCH -------------
// Shared with other components with tables.
// For case insensitive search.
// THIS NEEDS TO BE CLEANED UP BUT I'M MOVING ON, MAYBE LATER
public filterBy = (filterValue, column) => {
return (item) => {
const charTest = item[column].charAt(0);
if (charTest === filterValue.toLowerCase()) {
return true;
} else if (charTest === filterValue.toUpperCase()) {
return true;
} else {
return false;
}
}
};