如何在 Angular 17 中使用带有 @defer 的异步管道在模板中加载和声明变量

How can I use async pipe with @defer to load and declare variable in template in Angular 17

提问人:imalphachild 提问时间:11/14/2023 最后编辑:Matthieu Rieglerimalphachild 更新时间:11/15/2023 访问量:128

问:

例如,使用 ,我能够做到这一点:)。我能够使用模板中的“as”关键字将“items”声明为包含项目数组的变量。@if@if(items$ | async; as items

我怎样才能使用@defer实现同样的事情? 像这样:@defer(when items$ | async; as items)

我试过了,但 angular 模板不喜欢它。@defer(when items$ | async; as items)

Angular 异步 管道 延迟 angular-template

评论

1赞 Andrew Allen 11/14/2023
目前看起来不支持这种语法 - “当将命令性条件指定为返回布尔值的表达式时” - angular.dev/guide/defer#triggers 尽管我确实没有变量工作。考虑在 angular github 上打开功能请求when items$ | async
0赞 imalphachild 11/15/2023
好的,谢谢,我将添加为功能请求。

答:

1赞 Daniel B 11/14/2023 #1

延迟视图非常适合处理可观察对象或承诺,但 your 不是控制流的有效选项。您必须将其移动到块中。as items@defer@for

3赞 Matthieu Riegler 11/14/2023 #2

@defer块不允许创建别名,只有块允许创建别名。@if

你应该简单地用一个块包裹你。@defer@if

@if(items$ | async; as items) {
   @defer() {
      ...
   }
} else {
  ...
}

评论

0赞 imalphachild 11/15/2023
是的,我不得不走这条路,但我真的很喜欢“defer”附带的“占位符”块,它允许您指定在显示实际内容之前显示加载元素的时间。如果我能在模板上显示内容之前使用计时器等待数据时加载占位符就好了。可能不是这个主题的一部分,但如果你有办法我可以做到这一点,那会很酷,但现在我将添加一个功能请求,看看 angular 是否可以添加这个。谢谢!
0赞 Andrew Allen 11/15/2023 #3

要获取占位符行为,

堆栈闪电战

import 'zone.js';
import { Component, computed } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AsyncPipe } from '@angular/common';
import { of, delay } from 'rxjs';
import { toSignal } from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [AsyncPipe],
  template: `

    @defer (when loaded()) {
      <h1>DEFERRED</h1>
      @for(item of items(); track item) {
        <div>{{item}}</div>
      }
    } @placeholder {
      <p>PLACEHOLDER</p>
    }
  `,
})
export class App {
  name = 'Angular';
  items$ = of([1, 2, 3, 4]).pipe(delay(3000));
  items = toSignal(this.items$);

  loaded = computed(() => {
    return !!this.items()?.length;
  });
}

bootstrapApplication(App);

评论

1赞 Andrew Allen 11/15/2023
@defer (when items())也有效