当前位置: 首页 > 知识库问答 >
问题:

在离开页面之前警告用户未保存的更改

艾飞宇
2023-03-14

我想在用户离开angular 2应用程序的特定页面之前警告他们未保存的更改。通常我会使用<代码>窗口。onbeforeunload,但这不适用于单页应用程序

我发现在角1中,您可以连接到$locationChangeStart事件以为用户抛出确认框,但我还没有看到任何内容说明如何让它在角2中工作,或者该事件是否仍然存在。我还看到了为onbeforeunload提供功能的ag1插件,但同样,我还没有看到任何将其用于ag2的方法。

我希望其他人能找到解决这个问题的办法;这两种方法对我来说都很好。

共有3个答案

艾志尚
2023-03-14

stewDebaker中@Hostlistener的示例运行得非常好,但我对其进行了另一项更改,因为IE和Edge显示了MyComponent类上的canDeactive()方法返回给最终用户的“false”。

组件:

import {ComponentCanDeactivate} from "./pending-changes.guard";
import { Observable } from 'rxjs'; // add this line

export class MyComponent implements ComponentCanDeactivate {

  canDeactivate(): Observable<boolean> | boolean {
    // insert logic to check if there are pending changes here;
    // returning true will navigate without confirmation
    // returning false will show a confirm alert before navigating away
  }

  // @HostListener allows us to also guard against browser refresh, close, etc.
  @HostListener('window:beforeunload', ['$event'])
  unloadNotification($event: any) {
    if (!this.canDeactivate()) {
        $event.returnValue = "This message is displayed to the user in IE and Edge when they navigate without using Angular routing (type another URL/close the browser/etc)";
    }
  }
}
郝昊天
2023-03-14

路由器提供生命周期回调CanDe激活

有关更多详细信息,请参阅警卫教程

class UserToken {}
class Permissions {
  canActivate(user: UserToken, id: string): boolean {
    return true;
  }
}
@Injectable()
class CanActivateTeam implements CanActivate {
  constructor(private permissions: Permissions, private currentUser: UserToken) {}
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {
    return this.permissions.canActivate(this.currentUser, route.params.id);
  }
}
@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamCmp,
        canActivate: [CanActivateTeam]
      }
    ])
  ],
  providers: [CanActivateTeam, UserToken, Permissions]
})
class AppModule {}

原始(RC. x路由器)

class CanActivateTeam implements CanActivate {
  constructor(private permissions: Permissions, private currentUser: UserToken) {}
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
    return this.permissions.canActivate(this.currentUser, this.route.params.id);
  }
}
bootstrap(AppComponent, [
  CanActivateTeam,
  provideRouter([{
    path: 'team/:id',
    component: Team,
    canActivate: [CanActivateTeam]
  }])
);
杨凌
2023-03-14

为了防止浏览器刷新、关闭窗口等(有关此问题的详细信息,请参阅@ChristopheVidal对Gunter答案的评论),我发现在类的canDeactivate实现中添加HostListener装饰器很有帮助,可以在卸载前监听窗口事件。正确配置后,这将同时防止应用程序内和外部导航。

例如:

组件:

import { ComponentCanDeactivate } from './pending-changes.guard';
import { HostListener } from '@angular/core';
import { Observable } from 'rxjs/Observable';

export class MyComponent implements ComponentCanDeactivate {
  // @HostListener allows us to also guard against browser refresh, close, etc.
  @HostListener('window:beforeunload')
  canDeactivate(): Observable<boolean> | boolean {
    // insert logic to check if there are pending changes here;
    // returning true will navigate without confirmation
    // returning false will show a confirm dialog before navigating away
  }
}

警卫:

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

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

@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
  canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
    // if there are no pending changes, just allow deactivation; else confirm first
    return component.canDeactivate() ?
      true :
      // NOTE: this warning message will only be shown when navigating elsewhere within your angular app;
      // when navigating away from your angular app, the browser will show a generic warning message
      // see http://stackoverflow.com/a/42207299/7307355
      confirm('WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
  }
}

路线:

import { PendingChangesGuard } from './pending-changes.guard';
import { MyComponent } from './my.component';
import { Routes } from '@angular/router';

export const MY_ROUTES: Routes = [
  { path: '', component: MyComponent, canDeactivate: [PendingChangesGuard] },
];

模块:

import { PendingChangesGuard } from './pending-changes.guard';
import { NgModule } from '@angular/core';

@NgModule({
  // ...
  providers: [PendingChangesGuard],
  // ...
})
export class AppModule {}

注:正如@JasperRisseeuw所指出的,IE和Edge处理预卸载前事件的方式与其他浏览器不同,并且当预卸载前事件激活时(例如浏览器刷新、关闭窗口等),IE和Edge会在确认对话框中包含单词“false”。在Angular应用程序中导航不受影响,并将正确显示您指定的确认警告消息。那些需要支持IE/Edge且不想在卸载前事件激活时在确认对话框中显示/想要更详细消息的人,可能还想查看@JasperRisseeuw的解决方法答案。

 类似资料:
  • 问题内容: 我是angularjs新蜜蜂。我正在尝试编写一个验证,当用户尝试关闭浏览器窗口时会发出警告。 我的页面v1和v2上有2个链接。单击链接时,它指向特定页面。这是重定向到v1和v2的代码 当用户单击v1时,我想弹出一条消息,“如果他希望继续,他将从v1离开”,而单击v2时也是如此。任何有关如何实现这一目标的指针将不胜感激。 我在这里得到了答案,但是在每个时间间隔后都会弹出该消息。 更新的代

  • 问题内容: 我们使用jQuery的全局ajaxError()处理函数来警告用户任何AJAX失败: 不幸的是,如果用户在完成加载之前离开页面,则也会触发此全局错误处理程序。下面是重现该错误的步骤: 用户访问页面A,页面A包含通过AJAX加载的元素。 A页上的AJAX元素开始加载。 在页面A上的AJAX元素加载完成 之前, 用户单击链接即可访问页面B。 在浏览器重定向到页面B之前,错误对话框将短暂出现

  • 问题内容: 我希望我的ReactJS应用在离开特定页面时通知用户。特别是一条弹出消息,提醒他/她进行以下操作: “更改已保存,但尚未发布。现在执行吗?” 我应该在全局范围内触发此操作,还是可以在react页面/组件内完成此操作? 我还没有发现任何关于后者的信息,我宁愿避免使用第一个。除非当然是其规范,否则这使我想知道如何执行这样的事情而不必向用户可以访问的所有其他可能的页面添加代码。 欢迎有任何见

  • 我有一个<code>用户名 然后我有一个

  • 前提是已登录 前后端分离,当用户打开界面的时候,浏览器请求服务端的 nginx 获取 html+js+css 这些静态文件绘制界面 但是这些 html+js+css 可能是 vue 或者 react 编译出来的,本身不包含 user 信息 我想到的办法就是,浏览器绘制好了界面之后(或者绘制中),发出 ajax 请求后端 api 接口获取当前用户是谁 然后把 user 信息一起绘制到界面上 但是我看

  • 问题内容: 下面是到目前为止的代码 如何发出警报或是否有一些未保存的数据,以便用户决定是否继续? 问题答案: 这样的事情应该做到: 请注意,在此示例中未触发$ locationChangeStart的侦听器,因为在这样一个简单的示例中AngularJS不处理任何路由,但它应在实际的Angular应用程序中运行。