📜  如果我们第一次单击取消,CanDeactivate 不起作用 (1)

📅  最后修改于: 2023-12-03 15:38:59.120000             🧑  作者: Mango

如何使用CanDeactivate守卫

Angular的CanDeactivate守卫用于处理用户在离开当前页面时的取消操作。当用户点击“取消”按钮时,CanDeactivate守卫可以阻止用户离开当前页面。

如果CanDeactivate守卫不起作用

如果我们第一次单击取消,CanDeactivate守卫可能不起作用。这是因为Angular仅在表单处于“脏”(即在用户对表单进行更改后)时才会触发CanDeactivate守卫。

为了在用户第一次单击取消时也触发CanDeactivate守卫,我们需要手动将表单标记为“脏”。我们可以通过以下方式将表单标记为“脏”:

this.myForm.markAsDirty();

将此代码放在取消按钮单击事件的处理程序中,即可在用户第一次单击取消时,触发CanDeactivate守卫。

完整示例

下面是一个使用CanDeactivate守卫的完整示例。在这个示例中,我们创建了一个简单的表单,当用户在表单上进行更改但不提交时,点击页面中的任何链接都会触发CanDeactivate守卫。

import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';

export interface CanComponentDeactivate {
  canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}

@Injectable({
  providedIn: 'root'
})
export class ConfirmDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
  canDeactivate(component: CanComponentDeactivate) {
    const can = component.canDeactivate();
    if (can instanceof Observable) {
      return can;
    } else {
      return true;
    }
  }
}

@Component({
  selector: 'app-root',
  template: `
    <form [formGroup]="myForm">
      <input type="text" formControlName="name">
      <button (click)="onCancel()">取消</button>
    </form>
  `
})
export class AppComponent implements CanComponentDeactivate {
  myForm = new FormGroup({
    name: new FormControl('')
  });
  private isDirty = false;

  constructor(private router: Router) {}

  onCancel() {
    if (this.isDirty) {
      this.router.navigate(['/']);
    } else {
      this.myForm.markAsDirty();
      this.isDirty = true;
    }
  }

  canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
    if (this.isDirty) {
      return confirm('确定离开此页面吗?');
    } else {
      return true;
    }
  }
}

在这个示例中,当用户在表单上进行更改时,我们将表单标记为“脏”,并将isDirty变量设置为true。在用户尝试离开当前页面时,我们使用CanDeactivate守卫来检查表单是否已更改并询问用户是否确定要离开。

通过使用CanDeactivate守卫,我们可以确保用户在离开当前页面时不会无意中丢失他们所做的更改。