我正在尝试设置可以搜索的项目目录。我的目录组件有几个可观察的订阅。每当更新搜索词时,它都会将该查询应用于项列表并返回匹配项。搜索功能位于一个单独的组件中,该组件执行过滤并向searchService发送一个值以指示它何时开始和停止搜索。我想通过单独的加载器订阅来利用这个值更改并更新" isLoading" boolean在搜索函数运行时显示微调器。
catalog.cmp.ts:
ngOnInit(){
this.dataService.getData().subscribe((res) =>{
this.stock = res;
this.allstock = res;
});
this.searchsubscription = this.searchService.termUpdate$.subscribe(
(item) => {
this.searchTerm = item;
//the following searches through the allstock array and returns the list to be displayed with ngFor
this.stock = this.search.transform(this.allstock,{query:this.searchTerm})
},
(err) => {console.log(err)}
);
this.loadsubscription = this.searchService.loadUpdate$.subscribe(
(res) => {
this.toggleLoader(res)
},
(err) => {console.log(err)}
);
}
toggleLoader()函数如下所示:
toggleLoader(state){
this.isLoading = state;
console.log("ISLOADING",this.isLoading)
}
search.service.ts:
export class SearchService {
private isLoading;
private searchTerm = '';
private termSource = new BehaviorSubject<any>('');
termUpdate$ = this.termSource.asObservable();
private loadSource = new BehaviorSubject<boolean>(false);
loadUpdate$ = this.loadSource.asObservable();
constructor(){}
setTerm(term){
this.searchTerm = term;
this.termSource.next(term);
console.log(this.searchTerm, 'term updated')
}
getTerm(){
return this.searchTerm;
}
setLoadState(state: boolean){
this.isLoading = state;
this.loadSource.next(state);
console.log(this.isLoading, 'loading status')
}
getLoadState(){
return this.isLoading;
}
}
在我的组件模板中,我有这个设置:
<div>{{isLoading}}, {{searchTerm}} <-- this part is for debugging
<spinner *ngIf="isLoading"></spinner>
<button (click)="toggleLoader(true)">true</button>
<button (click)="toggleLoader(false)">false</button>
</div>
<span *ngIf="!isLoading">
<div class="row"
*ngFor="let item of stock| paginate: { itemsPerPage: 10, currentPage: p }">
...
</div>
</span>
因此除了isLoading值之外,视图的每个方面都会更新。但isLoading的正确值在控制台中和正确的时间显示(当发送搜索项并且过滤器正在运行时为true,当返回新的库存数组时为false,并且为更新提供ng)。在视图中没有检测到更改。我的toggleLoader调试按钮会正确更新视图。
我尝试过在类似问题中发布的许多解决方案,例如在zone.run()中包装toggleLoader的主体,或者使用ChangeDetectorRef手动调用更改检测。我甚至可以尝试不使用loadsubscription,而是在我调用search.transform之前调用toggleLoader,并在完成后再调用toggleLoader,如下所示:
this.searchsubscription = this.searchService.termUpdate$.subscribe(
(item) => {
this.searchTerm = item;
this.toggleLoader(true); //the console is still updated at the correct times with this method
this.stock = this.search.transform(this.allstock,{query:this.searchTerm})
this.toggleLoader(false);
},
(err) => {console.log(err)}
);
最小的掠夺者:https://plnkr.co/edit/lD4gZq 注意:在完整的应用程序中,搜索栏不是目录的子组件,这就是搜索词更新通过外部服务进行访问的原因。
我一直在研究变更检测,并尝试解决这个问题一段时间,但老实说,我无法弄清楚为什么这种情况不起作用。任何帮助,将不胜感激。感谢。