Angular2 - 防止 ngOnDestroy 发生

fra*_*nco 9 javascript angular

我有一个页面,它有一个表单,可以在用户离开之前检查用户是否有未保存的更改。

问题是,即使使用 preventDefault() 并返回 false,用户仍然可以单击远离组件。

有没有办法防止 ngOnDestroy 或 click 事件发生?

注意:用户不会去不同的路线,只是来自同一组件的另一个选项卡。

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jun*_*aid 6

你会想要使用 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;
  }

}
Run Code Online (Sandbox Code Playgroud)

2.在你的 app.module providers 中添加你的守卫服务(CanDeactivateGuard)

providers: [
    CanDeactivateGuard,
]
Run Code Online (Sandbox Code Playgroud)

3. 将您的路由更新为如下所示:

{
    path: "pipeline/:id",
    component: OnePipelineComponent,
    canDeactivate: [CanDeactivateGuard],
  },
Run Code Online (Sandbox Code Playgroud)

4.canDeactivate在您想要防止 ngOnDestroy 的组件中实现方法。就我而言,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;
}
Run Code Online (Sandbox Code Playgroud)

注意:显然,只需执行第 1 步和第 2 步一次,只需对您想要相同行为的其他每个组件重复第 3 步和第 4 步,意思是防止 ngOnDestroy 或换句话说,在组件被销毁之前做某事) .

查看这些文章以获取代码示例和上面编写的代码的解释。CanDeactivate和CanDeactivate Guard 示例


rmc*_*rry 5

您正在混合两个概念 - 离开意味着前往新路线。正确的角度解决方案是实施 CanDeactivateGuard。有关于此的文档在这里。

这里有一个堆栈溢出问题及其答案。

在您的情况下,用户不会导航到新页面(即路线不会更改)。他们只需点击一个新选项卡即可。

如果没有看到更多代码,就很难知道这两个选项卡是同一表单的一部分还是两种不同表单的一部分。

但无论如何,您需要在另一个选项卡按钮上有一个单击处理程序,并且在该单击处理程序中您需要检查当前选项卡的数据是否未保存(即,如果该选项卡是一个单一表单,则该表单是否脏?)。

因此,基本上将您发布的代码从该点击处理程序移入ngOnDestroy或移入该点击处理程序。