如何在Angular中重试异步调用并重新触发@defer/@placeholder块?
实现@defer重试时重新显示占位图的方案
根据Angular官方文档说明,@defer块一旦触发切换到内容后,就不会再自动回到占位符,因为这是一次性操作。要实现点击重试按钮时重新执行异步调用并显示占位图,核心是让@defer的触发条件能重新触发加载流程。
具体实现步骤
- 创建触发信号:用一个计数器信号控制@defer的触发,每次重试时更新信号,让@defer重新启动加载流程。
- 修改@defer触发条件:使用
onSignal()触发器绑定计数器信号,确保每次信号更新都能触发@defer重新加载。 - 封装异步加载逻辑:把异步调用和信号更新放在同一个方法里,初始加载和重试时统一调用。
完整代码示例
组件类代码
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
相关产品推荐
相关产品推荐

