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

Angular:关闭Mat-Dialog后如何向CanDeactivate Guard返回值

Fixing CanDeactivate Guard with Angular Material Dialog for Unsaved Changes

Looking at your code, the main issue is that your confirmDialog() method returns a Subscription (from calling subscribe() on dialogRef.afterClosed()) instead of the Observable<boolean> that the CanDeactivate guard expects. This means the guard can’t properly handle the asynchronous dialog result to control navigation.

Here’s how to fix this step by step:

1. Update the confirmDialog() method in UnsavedChangesComponent.ts

Instead of subscribing directly, return the observable from afterClosed() and use pipe(tap(...)) to handle save/cancel logic as a side effect. This keeps the observable chain intact for the guard to use:

import { tap } from 'rxjs/operators';
import { Observable } from 'rxjs';

// ...

confirmDialog(): Observable<boolean> {
  const dialogRef = this.dialog.open(ConfirmDialogComponent, {
    width: '450px',
  });

  return dialogRef.afterClosed().pipe(
    tap(result => {
      if (result === true) {
        // Execute save action when user confirms
        this.save();
      }
      // No extra logic needed for false result—we just let the observable pass the value to the guard
    })
  );
}

2. Why this works

  • dialogRef.afterClosed() returns an Observable<any> that emits the dialog’s close result (true/false in your setup).
  • Using tap() lets us run the save logic without modifying the emitted value. The observable will still pass through true or false, which the guard uses to decide navigation:
    • If result === true: We save changes, then the guard receives true to allow navigation
    • If result === false: The guard receives false to block navigation (keeping the user on the page)

3. Your DeactivateGuard stays unchanged

The guard is already configured to handle Observable<boolean>, so no modifications are needed here:

export class DeactivateGuard implements CanDeactivate<UnsavedChangesComponent> {
  canDeactivate(
    component: UnsavedChangesComponent,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
    if (component.isDirty) {
      return component.confirmDialog();
    } else {
      return true;
    }
  }
}

4. Confirm your dialog component logic

Double-check that your ConfirmDialogComponent closes with the correct values to match your intended flow:

confirmDialog.ts:

import { MatDialogRef } from '@angular/material/dialog';

// ...

constructor(public dialogRef: MatDialogRef<ConfirmDialogComponent>) {}

save(){
  this.dialogRef.close(true);
}
cancel() {
  this.dialogRef.close(false);
}

confirmDialog.html:

<button mat-button color="primary" (click)="save()">Save Changes</button>
<button mat-button color="warn" (click)="cancel()">Stay on Page</button>

(Adjust button text if needed to align with your user-facing labels)

This setup ensures the guard correctly reacts to the user’s dialog choice: saving changes before navigation if they select "Save", or keeping them on the page if they select "Cancel".

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:21:28