【问题标题】:Angular doesn't update the view on arrival of new dataAngular 不会在新数据到达时更新视图
【发布时间】:2020-01-13 13:48:33
【问题描述】:

我在导航栏中定义了一个搜索输入字段: <input type="search" class="form-control" [formControl]="search" placeholder="search" aria-label="search">

在其控制器中,我订阅更改并将其转发到搜索服务:

this.search
  .valueChanges
  .subscribe(v => {
    this.searchService.setSearchValue(v);

    if (this.changeDetectorRef !== null && this.changeDetectorRef !== undefined &&
      !(this.changeDetectorRef as ViewRef).destroyed) {
      this.changeDetectorRef.detectChanges();
    }
  });
}

搜索服务持有该值,其他组件可以请求它。

searchValue: Subject<string>;

getSearchValue(): Observable<string> {
    return this.searchValue;
}

setSearchValue(searchValue: string) {
    this.searchValue.next(searchValue);
}

在我的数据视图中,我显示了由搜索值过滤的所有数据:

<div *ngIf="(services | search:searchValue) as result">
    <div *ngFor="let service of result">
        {{ service.name }}
    </div>
</div>
this.searchService.getSearchValue().subscribe(value => {
    console.log("new search value: " + value);
    this.searchValue = value;
});

但视图不会在第一次击键时更新,只会在第二次击键后自行更新。

我知道正确的搜索值到达组件,因为 console.log 包含预期值,但视图仍然没有更新。在我看来,我也尝试过changeDetectorRef.detectChanges()searchPipe.transform(this.services, value),但没有成功。

谁能告诉我出了什么问题?提前致谢。

【问题讨论】:

  • 你能不能在 jsfiddle 或其他可以检查行为的网站上做一个小项目?
  • 我看不到您的方法会立即出现错误。请注意,您没有在组件类中创建变量并手动订阅,async 管道可以帮助您;即&lt;ng-container *ngIf="searchValue | async as result"&gt; &lt;div *ngFor="let service of result"&gt; &lt;!-- and so on --&gt;
  • 感谢您的回答,不幸的是,对我没有任何帮助。这是我的问题的StackBlitz

标签: angular


【解决方案1】:

首先。你不必使用这样的一段代码:

      if (this.changeDetectorRef !== null && this.changeDetectorRef !== undefined &&
          !(this.changeDetectorRef as ViewRef).destroyed) {
          this.changeDetectorRef.detectChanges();
        }

我想有时你会发现异常,这就是为什么你不取消订阅 this.search.valueChanges 或者你的逻辑非常奇怪。

尝试使用BehaviorSubject 而不是Subject,区别在于Subject 不存储最后发出的值,而BehaviorSubjects 存储。 也许您的某个组件或服务的初始化速度比其他组件快,并且您的 Subject 已经触发了值。

【讨论】:

    【解决方案2】:

    假设您在 ngonInit 中执行以下代码

    this.searchService.getSearchValue().subscribe(value => {
        console.log("new search value: " + value);
        this.searchValue = value;
    
        // Run the change detection here 
        this.changeDetectorRef.detectChanges();
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      • 2019-07-04
      • 2021-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多