【问题标题】:Angular ? after as in ngIf角?在 ngIf 之后
【发布时间】:2020-02-11 00:51:57
【问题描述】:

我正在尝试执行以下操作:

<div *ngIf="(observable$ | async) as results?.length > 0"> <-- here is the error
  <span *ngFor="let result of results>{{result}}</span>"

即仅当结果可用且结果超过 1 个时才绘制此 &lt;div&gt;

第一行&lt;div&gt; 导致错误。存在两个&lt;div&gt;s 的解决方案:

<div *ngIf="(observable$ | async) as results">
  <div *ngIf="results?.length > 0">
    <span *ngFor="let result of results>{{result}}</span>"

可以在单个&lt;div&gt; 中完成而不添加另一个容器吗?

【问题讨论】:

  • 不确定,但试试((observable$ | async) as results)?.length &gt; 0
  • @EliasSoares 谢谢,但它不起作用。
  • 我会将这么多的逻辑交给控制器并保持模板干净。
  • @Phix 我不敢苟同。模板应该处理要显示的内容,控制器只提供数据。

标签: angular


【解决方案1】:

? 不能在 *ngIf 语句中与 as 一起使用。你能做的最好的就是(observable$ | async)?.length &gt; 0

此外,当您不需要以 HTML 呈现的两个嵌套 divs(或任何其他,但您仍然需要 *ngIf / *ngFor)时,您可以使用不会呈现为 HTML 的 &lt;ng-container&gt;元素:

<ng-container *ngIf="(observable$ | async) as results">
  <div *ngIf="results?.length > 0">
    <span *ngFor="let result of results>{{result}}</span>

如果您试图在迭代之前检查一个元素是否为空,您实际上不需要明确地检查它,因为*ngFor 将优雅地处理空数组/列表。因此,您应该能够将您的模板简化为:

<ng-container *ngIf="(observable$ | async) as results">
  <span *ngFor="let result of results>{{result}}</span>

甚至更进一步:

<div *ngFor="let item of observable$ | async">{{result}}</div>

【讨论】:

  • 感谢您提供许多替代方案,它们应该对其他人有用。所以回到我原来的问题,你相信没有办法使用吗?在as之后?
  • 你不能用?与作为。你能做的最好的就是(observable$ | async)?.length &gt; 0
  • 好的,请在你的答案中添加这个,这样我就可以选择你的作为答案,因为这是我问的,然后你可以建议像上面这样的替代方案。
【解决方案2】:

在这种情况下,我喜欢使用两个 div,因为它让我感觉更干净、更易读。不过,这对不同的人来说是不同的,所以这真的是你的偏好。

<div *ngIf="observable$ | async as results">
  <div *ngIf="results && results.length > 0">
    <span *ngFor="let result of results>{{result}}</span>"
  </div>
</div>

【讨论】:

  • 谢谢。是的,存在两个 div 解决方案。我追求一个 div 解决方案。
【解决方案3】:

您不能在同一元素上使用 *ngFor*ngIf,因此您可以使用 ng-container 来防止在输出中包含额外的 div 包装器:

<ng-container *ngIf="(observable$ | async).length; else noContent">
  <div *ngFor="let result of (observable$ | async)">
    <h3>{{ result.name }}</h3>
    <p>{{ result.price | currency }}</p>
  </div>
</ng-container>

<!-- optional -->
<ng-template #noContent>
    Nothing to show.
</ng-template>
import { Component, OnInit } from "@angular/core";
import { of, Observable } from "rxjs";
import { map, filter, tap } from "rxjs/operators";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  observable$: Observable<{name: string, price: number}[]>;

  ngOnInit() {
    // To simulate requests with some/no results 
    // Change to 1 to always return data, 0 for empty results.
    const chance = Math.random();
    this.observable$ = this.getMockData(chance).pipe(
      map(res => res.results)
    );
  }

  getMockData(random) {
    const results =
      random <= 0.5
        ? { results: [] }
        : {
            results: [
              { name: "Widget", price: 300 },
              { name: "Widget 2", price: 50 },
              { name: "Widget 3", price: 75 }
            ]
          };
    return of(results);
  }
}

输出:

<div _ngcontent-sqx-c0="">
  <h3 _ngcontent-sqx-c0="">Widget</h3>
  <p _ngcontent-sqx-c0="">$300.00</p>
</div>
<div _ngcontent-sqx-c0="">
  <h3 _ngcontent-sqx-c0="">Widget 2</h3>
  <p _ngcontent-sqx-c0="">$50.00</p>
</div>
<div _ngcontent-sqx-c0="">
  <h3 _ngcontent-sqx-c0="">Widget 3</h3>
  <p _ngcontent-sqx-c0="">$75.00</p>
</div>

Stackblitz

【讨论】:

  • 谢谢。但是很抱歉,如果我的问题在这里引起了一些混乱。我不是在问将ngIfngFor 组合在一个容器中,我的问题标题说使用?在as 之后。有问题的行是*ngIf="(observable$ | async) as results?.length &gt; 0",这会导致错误。我添加的&lt;span&gt;只是为了完成代码段,与我的问题无关。
猜你喜欢
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
  • 2019-03-31
  • 1970-01-01
  • 2019-03-23
  • 2017-06-08
相关资源
最近更新 更多