我使用Ngfor(cdkVirtualFor(中的behaviourSubject来监视一组切换按钮的更改,这些按钮通过TypeNumber过滤项目列表。
现在,我的老板还想添加一个搜索输入框,根据搜索词过滤相同的列表。
我正在筛选行为主题,但一旦我在输入框中输入搜索词,列表就会变为空白,如果我清除搜索框,它就不会恢复正常。
我做错了什么?当列表是数组时,我可以过滤它,但当它是可观察/行为主题时,我无法使其工作。
模板
<div class="field">
<label class="label" for="searchinput-0">Search Input</label>
<div class="control">
<input id="searchinput-0" name="searchinput-0" type="text" placeholder="Search staff"
class="input is-rounded search-query" [(ngModel)]="searchTerm">
</div>
</div>
<div class="notification column is-10">
<cdk-virtual-scroll-viewport itemSize="100">
<li *cdkVirtualFor="let p of courses" class="animated slideInRight">
<div [ngSwitch]="p.typeNumber">
<span *ngSwitchCase="1">
<lis-elearning [learningItem]="p"></lis-elearning>
</span>
<span *ngSwitchCase="2">
<lis-instructor [learningItem]="p"></lis-instructor>
</span>
<span *ngSwitchDefault>This the default case</span>
</div>
</li>
</cdk-virtual-scroll-viewport>
组件
constructor() {
this.storage = { courses: [], filteredCourses: [], courseType: [], filterOptions: {}};
this.coursesSubject = new BehaviorSubject([]) as BehaviorSubject<ILearningItem[]>;
this.courseTypesSubject = new BehaviorSubject([]) as BehaviorSubject<ILearningType[]>;
this.courses = this.coursesSubject.asObservable();
this.courseType = this.courseTypesSubject.asObservable();
}
// This setter is called everytime the value in the search text box changes
set searchTerm(value: string) {
this._searchTerm = value;
this.courses = this.filterCourses(value);
}
filterCourses(searchString: string) {
return this.courses
.pipe(map((courses) => courses.filter( course => course.Name === searchString)
));
}
编辑:添加了Stacklitz-如何添加将过滤相同列表的搜索框?-https://stackblitz.com/edit/angular-rxjs-multi-option-filter
好的,要解决Stacklitz上产生的问题,只需遵循以下步骤:
- 首先使用NPM安装
ngx-filter-pipe
(您可以跳过此操作,stackblitz将建议您在之后进行安装( - 然后在
app.module
中添加import { FilterPipeModule } from 'ngx-filter-pipe';
,并将FilterPipeModule
添加到imports[]
- 在
app.component.ts
中添加变量itemFilter: any = { name: '' };
- 在app-component.html中,将
*ngFor
更改为*ngFor="let item of courses | async | filterBy: itemFilter"
- 内部
app.component.ts update
textFilter `功能如下:
public textFilter(ref){ this.itemFilter.name = ref; }
现在一切都应该按预期工作
每次键入时都会创建新的可观测值,返回可观测值的getter函数会不断返回新的可观察值。使用组合最新创建可观察到的。
searchTerm$ = new BehaviorSubject<string>('');
courses$ = IDontKnowWhereYouGetYourCoursesObservable;
filteredCourses$ = combineLatest(this.searchTerm$, this.courses$).pipe(
map(([searchTerm, courses]) => courses.filter(course => course.Name === searchTerm))
)
并使用更新searchTerm$
<input (change)="searchTerm$.next($event.value)">
<li *cdkVirtualFor="let p of filteredCourses$ | async">