【问题标题】:Check if Observable is empty is not possible, so what other option I have?检查 Observable 是否为空是不可能的,那么我还有什么其他选择?
【发布时间】:2021-05-23 04:32:16
【问题描述】:

我写了一个 Angular 11,我对 Observables 和 Subjects 还很陌生。

我有一个mat-autocomplete 组件,它的结果分为几类。最后一个类别是文章类别,我使用此代码显示它:

组件代码:

private readonly searchResultArticles = new Subject<Article[]>(); 

get searchResultArticles$(): Observable<Article[]> {
   return this.searchResultArticles;
}

模板:

<mat-optgroup label="Articles">
        <mat-option *ngFor="let article of searchResultArticles$ | async" [value]="article">
          <img class="example-option-img" aria-hidden [src]="getArticleThumbnail(article.profile_dir,article.title)" height="25" />
          <span class="cocktail_name_search_result" *ngIf="article.title" [innerHTML]="article.title | highlight : autoCompleteInput.value : 1"></span>
          &nbsp;-&nbsp;
          <span class="cocktail_desc_search_result" *ngIf="article.desc" [innerHTML]="article.desc | highlight : autoCompleteInput.value : 1"></span>

        </mat-option>
      </mat-optgroup>

所以即使searchResultARticles$ Observable 中没有项目,也会显示带有标签Articlesmat-optgroup。 如果没有项目,我希望能够隐藏这个mat-optgroup

我想过做:

<mat-optgroup label="Articles" *ngIf="(searchResultArticles$ | async).length>0">

但这会导致一些奇怪的行为,有时项目不会出现,我想我只能使用一次异步?我想我需要多读一些。

但无论如何.. 有什么优雅的方法可以解决这个问题?

谢谢

【问题讨论】:

  • 不应该是*ngIf="(searchResultArticles$() | async).length&gt;0"吗? 强调$后的()
  • @NicholasK no searchResultArticles$ 是一个没有 () 的调用

标签: angular typescript angular-observable


【解决方案1】:

首先,我想将 observable 分配给组件中的 searchResultArticles$ 字段。然后我将异步管道的结果分配给模板变量。洞的东西应该是这样的:

类代码:

  searchResultArticles$: Observable<Article[]>;

  constructor(private http: HttpClient) {
  }

  getSearchResultArticles$(): Observable<Article[]> {
    // get articles from somewhere, at best from a separate service class
     return this.http.get<Article[]>(`/articles`);
  }

  ngOnInit() {
    this.searchResultArticles$ = this.getSearchResultArticles$();
  }

模板代码:

  <mat-optgroup label="Articles" *ngIf="searchResultArticles$ | async as searchResultArticles">
    <mat-option *ngFor="let article of searchResultArticles" [value]="article">
      <img class="example-option-img" aria-hidden [src]="getArticleThumbnail(article.profile_dir,article.title)"
           height="25"/>
      <span class="cocktail_name_search_result" *ngIf="article.title" [innerHTML]="article.title | highlight : autoCompleteInput.value : 1"></span>
      &nbsp;-&nbsp;
      <span class="cocktail_desc_search_result" *ngIf="article.desc" [innerHTML]="article.desc  | highlight : autoCompleteInput.value : 1"></span>

    </mat-option>
  </mat-optgroup>

如果您想在 searchResultArticles 为空时省略整个组,请按照 @Thomas 的建议将其放入 ng-container

【讨论】:

    【解决方案2】:

    你需要知道的是async管道可以返回null。

    您的方法可能是:

    <ng-container *ngIf="searchResultArticles$ | async as data">
      <mat-optgroup *ngIf="data.length > 0" label="Articles">
    </ng-container>
    

    【讨论】:

    • null 事物的解决方案可能是?。运营商data?.length &gt; 0
    • @Andrei 在这种情况下不是,因为您不想订阅两次只是为了获取数据和长度。
    猜你喜欢
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    相关资源
    最近更新 更多