Angular2 - 防止ngOnDestroy发生

时间:2017-07-11 07:06:13

标签: javascript angular

我有一个页面,其中包含一个表单,用于在导航离开之前检查用户是否有未保存的更改。

问题是即使使用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;
        }
    }
}

2 个答案:

答案 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或换句话说,在 组件可以被破坏)。

查看这些文章以获取代码示例以及上面编写的代码的说明。 CanDeactivateCanDeactivate Guard Example