0

我正在尝试设置可以搜索的项目目录。我的目录组件有一些对 observables 的订阅。每当更新搜索词时,它都会将该查询应用于项目列表并返回匹配的项目。搜索功能位于一个单独的组件中,该组件执行过滤并向 searchService 发送一个值以指示它何时开始和停止搜索。我想通过单独的加载程序订阅来利用此值更改,并更新“isLoading”布尔值以在搜索功能运行时显示微调器。

目录.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,当返回新的股票数组并且 ngfor 更新时为 false)。视图中没有检测到更改。但是,我的 toggleLoader 调试按钮将正确更新视图。

我已经尝试了许多类似问题中发布的解决方案,例如将 toggleLoader 的主体包装在 zone.run() 中或使用 ChangeDetectorRef 手动调用更改检测。我什至可以尝试不使用 loadsubscription,而是在调用 search.transform 之前调用 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 注意:在完整的应用程序中,搜索栏不是目录的子组件,这就是为什么搜索词更新要通过外部服务进行。

我一直在研究变更检测并试图解决这个问题一段时间,但老实说我无法弄清楚为什么这不起作用。任何帮助,将不胜感激。谢谢。

4

0 回答 0