我的申请的结构大致如下:
<app-header></app-header> <app-main></app-main> <app-footer></app-footer>
标题包含此命令的链接:
this.keycloakService.logout();
它绕过了主要部分中的
"if (component.form.dirty)"
。我想问问用户,发生这种情况时是否要保存。
为此,您可以在表单路由定义上使用
canDeactivate
防护。下面给出一个简单的例子:
// route
{
path: APP_PATHS.SECTION.ASSIGN + '/:personId',
loadComponent: () =>
import(
'../person/person-assign/person-assign.component'
).then((m) => m.PersonAssignComponent),
canDeactivate: [formDeactivateGuard]
}
// guard
import { inject } from '@angular/core';
import { CanDeactivateFn } from '@angular/router';
import { DialogService } from '@shared/services/dialog.service';
import { FormService } from '@shared/services/form.service';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const formDeactivateGuard: CanDeactivateFn<any> = async () => {
const formService = inject(FormService);
const dialogService = inject(DialogService);
if (formService._isDirty.getValue()) {
return await dialogService
.openConfirmDialog({
title: 'form.unsaved-changes.title',
message: 'form.unsaved-changes.message',
confirmKey: 'common.leave',
cancelKey: 'common.cancel',
})
.then((result) => {
if (result) {
formService.setDirty(false);
return Promise.resolve(true);
} else {
return Promise.resolve(false);
}
});
} else {
return Promise.resolve(true);
}
};
// service
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class FormService {
public _isDirty = new BehaviorSubject<boolean>(false);
public setDirty(isDirty: boolean) {
this._isDirty.next(isDirty);
}
}
使用表单组件中的服务来设置 valueChanges 的脏状态。
实现这一目标的方法有很多,您的用例将决定哪一种适合您。在这里,我们使用的服务允许我们完全控制表单脏状态(我使用它是为了防止用户进行了更改,但这些更改与原始值相同,实际上等于没有更改),您可以或者使用抽象组件来监视表单状态并将其提供给警卫,从而减少重复。