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

如何在Angular(5)中结合ng-template实现结账页登录检测加载Spinner?

解决结账页面Spinner与模板同时显示的问题

这个问题的核心在于:你的模板在等待用户状态的过程中,auth.user | async还没返回确定值时,就已经触发了#guest模板的显示,同时Spinner也处于显示状态,导致两者同时出现。我们需要确保只有在用户状态完全确定后,才显示对应的登录/结账模板,之前只显示Spinner。

解决方案步骤

1. 调整组件中的加载状态跟踪

我们用一个isLoading变量来明确跟踪是否处于登录状态检测过程中,并确保无论用户状态是已登录还是未登录,只要状态确定就关闭加载:

export class CheckoutComponent implements OnInit {
  isLoading = true; // 初始处于加载状态
  constructor(public auth: AuthService, private router: Router) { }

  ngOnInit() {
    // 订阅用户状态,第一次收到值(无论用户是否登录)就结束加载
    this.auth.user.pipe(
      finalize(() => this.isLoading = false) // 确保即使订阅出错也能关闭Spinner
    ).subscribe(user => {
      // 这里可以添加额外的用户状态处理逻辑,比如用户为null时的跳转等
    });
  }
}

2. 修改模板结构,控制显示顺序

把所有认证相关的模板包裹在*ngIf="!isLoading"中,确保只有加载完成后才显示;同时把Spinner单独作为加载状态的展示:

<!-- 加载状态:只在isLoading为true时显示Spinner -->
<ng-template #loadingSpinner>
  <app-spinner></app-spinner>
</ng-template>

<!-- 加载完成后才显示认证/结账内容 -->
<div *ngIf="!isLoading; else loadingSpinner">
  <div *ngIf="auth.user | async; then authenticated else guest"></div>

  <!-- 用户未登录 -->
  <ng-template #guest>
    <div class="call-to-action"> login buttons... </div>
  </ng-template>

  <!-- 用户已登录 -->
  <ng-template #authenticated> payment steps </ng-template>
</div>

为什么原来的代码会出问题?

原来的代码中,auth.user | async在Observable还未发出第一个值(也就是还在检测登录状态时)会返回null或undefined,这会直接触发else guest分支显示登录按钮,而此时showSpinner仍然是true,导致Spinner和登录按钮同时出现。通过用isLoading控制整个认证区块的显示时机,就能避免这种情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:53:51