我有一个页面,其中包含一个表单,用于在导航离开之前检查用户是否有未保存的更改。
问题是即使使用preventDefault()并返回false,用户仍然可以点击该组件。
有没有办法防止ngOnDestroy或点击事件发生?
注意:用户不会使用其他路线,只是来自同一组件的其他标签。
ngOnDestroy() {
if (this.myForm.dirty) {
let save = confirm('You are about to leave the page with unsaved changes. Do you want to continue?');
if (!save) {
window.event.preventDefault();
return false;
}
}
}
答案 0 :(得分:2)
您正在混合两个概念 - 导航意味着新路线。对此的正确角度解决方案是实现CanDeactivateGuard。这方面的文档是here。
带答案的堆栈溢出问题是here。
在您的情况下,用户不会导航到新页面(即路线不会更改)。他们只是点击一个新标签。
如果没有看到更多代码,很难知道这两个标签是否属于同一表格或两种不同形式。
但无论如何,你需要在另一个标签按钮上点击处理程序,在那个点击处理程序中你需要检查当前标签的数据是否未保存(即如果该标签是一个单一的表格,那个表格是否脏? )。
所以基本上将您从ngOnDestroy
发布的代码移动到该单击处理程序中。
答案 1 :(得分:2)
您想使用CanDeactivate。这是一个示例。
1。创建警卫服务/提供者。
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
2。在您的app.module提供程序中添加您的警卫服务( CanDeactivateGuard )
providers: [
CanDeactivateGuard,
]
3。将您的路由更新 ,如下所示:
{
path: "pipeline/:id",
component: OnePipelineComponent,
canDeactivate: [CanDeactivateGuard],
},
4。在您要阻止ngOnDestroy 的组件中实现canDeactivate
方法。就我而言,就是上述路线中提到的OnePipelineComponent
。
canDeactivate() {
console.log('i am navigating away');
// you logic goes here, whatever that may be & must return either True or false
if (this.user.name !== this.editName) {
return window.confirm('Discard changes?');
}
return true;
}
注意: :显然,仅执行步骤1和2一次,对于您想要相同行为(即要执行以下操作)的每个其他组件重复步骤3和4 防止ngOnDestroy或换句话说,在 组件可以被破坏)。
查看这些文章以获取代码示例以及上面编写的代码的说明。 CanDeactivate和CanDeactivate Guard Example