You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular中重试异步调用并重新触发@defer/@placeholder块?

实现@defer重试时重新显示占位图的方案

根据Angular官方文档说明,@defer块一旦触发切换到内容后,就不会再自动回到占位符,因为这是一次性操作。要实现点击重试按钮时重新执行异步调用并显示占位图,核心是让@defer的触发条件能重新触发加载流程。

具体实现步骤

  1. 创建触发信号:用一个计数器信号控制@defer的触发,每次重试时更新信号,让@defer重新启动加载流程。
  2. 修改@defer触发条件:使用onSignal()触发器绑定计数器信号,确保每次信号更新都能触发@defer重新加载。
  3. 封装异步加载逻辑:把异步调用和信号更新放在同一个方法里,初始加载和重试时统一调用。

完整代码示例

组件类代码

import { Component, signal } from '@angular/core';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html'
})
export class YourComponent {
  // 计数器信号,用于触发@defer重新加载
  retryTrigger = signal(0);
  asyncData: any;
  hasError = false;

  ngOnInit() {
    // 初始加载数据
    this.loadAsyncData();
  }

  loadAsyncData() {
    // 重置错误状态
    this.hasError = false;
    // 更新计数器,触发@defer重新加载
    this.retryTrigger.set(this.retryTrigger() + 1);

    // 模拟异步API调用(替换为你的实际请求)
    fetch('your-api-endpoint')
      .then(response => response.json())
      .then(data => {
        this.asyncData = data;
      })
      .catch(() => {
        this.hasError = true;
      });
  }

  retryAsyncCall() {
    // 点击重试时重新加载数据
    this.loadAsyncData();
  }

  successOnRetrievingAsyncData() {
    return !!this.asyncData && !this.hasError;
  }
}

模板代码

@defer (onSignal(retryTrigger)) {
  @if (successOnRetrievingAsyncData()) {
    <success-component [data]="asyncData" />
  } @else {
    <error-component />
    <button (click)="retryAsyncCall()">Retry</button>
  }
} @placeholder(minimum 1s) {
  <img src="placeholder.png" alt="加载中..." />
}

原理说明

  • 计数器信号retryTrigger每次更新时,onSignal(retryTrigger)会触发@defer重新执行加载流程,此时占位符会再次显示,直到异步操作完成。
  • 异步加载前重置错误状态,确保重试流程的状态正确。
  • 这种方式利用了@defer的onSignal触发器特性:只要绑定的信号发生变化,就会重新触发加载,完美适配重试场景。

内容的提问来源于stack exchange,提问作者isy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 07:54:56