如何在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
相关产品推荐
相关产品推荐

