【问题标题】:Local variable in template for async pipe (angular 2+)异步管道模板中的局部变量(角度 2+)
【发布时间】:2021-10-20 17:51:16
【问题描述】:

我的模板有类似...

<div> {{ (profile$ | async).username}}</div>
<div> {{ (profile$ | async).email}}</div>

有没有办法将 (profile | async) 分配给局部变量?必须为每个字段都输入它不利于可读性。

谢谢。

【问题讨论】:

    标签: angular


    【解决方案1】:

    从 Angular 4.0.0-rc.1 (2017-02-24) 开始,您可以使用增强的 *ngIf 语法。这让您可以在模板局部变量中分配 *ngIf 条件的结果:

    <div *ngIf="profile$ | async as profile">
        <div>{{profile.username}}</div>
        <div>{{profile.email}}</div>
    </div>
    

    更新后的*ngIf documentation 更加详细,并提供了许多同时使用async*ngIf 的好例子。

    请务必查看*ngIfthenelse 语句。

    Cory Rolan 制作了一个short tutorial,您可以在 5-10 分钟内消化。

    【讨论】:

    • @Hinrich 不,实际上没关系。异步管道被记忆,并且在内部使用相同的订阅。唯一的好处是可读性
    • @Phil 其实不是这样的,最好使用一个变量,因为如果你多次使用管道它会为每一个创建不同的订阅,这可能不是什么你要。你可以很容易地检查它记录订阅。
    【解决方案2】:

    最好的方法是创建一个新组件,例如在这种情况下 app-profile 并将 profile | async 传递给该组件。在组件内部,您可以随意命名变量。

    <app-profile [profile]="profile | async"></app-profile>
    

    另一种方法是使用 *ngIf 和 'as' 语法

    <ng-container *ngIf="profile | async as p">
       <div> {{ p.username }}</div>
       <div> {{ p.email }}</div>
    </ng-container>
    

    【讨论】:

    • 是的,我已经看到了一些这样做的例子,这对于可重用性可能更好。谢谢!
    • 如果您使用 ChangeDetectionStrategy.OnPush,这并没有真正的帮助,因为您最终会在 app-profile 组件中使用 observable 来响应配置文件 @Input 中的更改跨度>
    • @chrismarx 不,在本例中,app-profile 输入变量 profile 不是可观察的。通过外部可观察 profile 的每个值都将通过异步管道传输,这会将单个值推送到输入中。这将触发 OnPush 更改检测,这将导致 app-profile 呈现新值。
    • @JasonJackson 嗯,我认为你是对的,我忘记了 onpush 更新对异步的更改以及“@Inputs”
    【解决方案3】:

    这有点老套,但我似乎有很多这样的例子:

    <template ngFor let-profile [ngForOf]="profile$ | async">
      <div> {{ profile.username }}</div>
      <div> {{ profile.avatar }}</div>
      <div> {{ profile.email }}</div>
      ...
    </template>
    

    【讨论】:

    • 这与&lt;div *ngFor="let profile of profile$ | async"&gt;有何不同?
    • @torazaburo 使用您提到的那个,您将在每次迭代中创建一个 &lt;div&gt; 包装器。 &lt;template&gt; element 不生成任何输出,仅用于定义布局中的块,但 &lt;template&gt; 不支持短语法 (*ngFor),仅支持长语法。
    • 我可以使用template 简单地将变量分配给可观察对象的最新值,而不是要循环的数组吗?
    • @torazaburo 也许,但我看不出有任何理由在你的模板中而不是在它自己的控制器上这样做。您仍然可以在模板中使用 observable,并从控制器向其添加另一个观察者,以便在其值更改时运行任何代码。通过在控制器中进行您提到的这个变量分配,您将拥有更多权力。希望这对你有任何意义。
    【解决方案4】:

    有一个替代方案,但它更乏味。 Günter Zöchbauer 提出的解决方案缓解了这一事实。

    另一种方法是订阅组件内部的 observable,然后在模板中使用订阅变量。您必须在 OnDestroy 事件中取消订阅以防止内存泄漏。异步管道为你做这件事。这就是为什么公认的解决方案更清洁的原因。但是,如果您不想创建新组件,这是可行的方法。

    【讨论】:

      【解决方案5】:

      如果您想访问内部vm$ 上的对象,例如这种类型vm$: Observable&lt;{ profile: {} }&gt;

      试试下面的 sn-p,不要忘记? 标记。

      <ng-container *ngIf="(vm$ | async)?.profile as profile">
        <div> {{ profile.username }}</div>
        <div> {{ profile.email }}</div>
      </ng-container>
      

      【讨论】:

        猜你喜欢
        • 2017-09-05
        • 1970-01-01
        • 1970-01-01
        • 2021-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-19
        • 1970-01-01
        相关资源
        最近更新 更多