Javascript 如何防止以角度 4 刷新页面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47331260/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:49:17  来源:igfitidea点击:

How to prevent page refresh in angular 4

javascriptangularangular-routing

提问by RajnishCoder

I want to prevent page refresh by everywhere.

我想防止到处刷新页面。

I tried the code below

我试过下面的代码

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { CommonServices } from '../services/common.service'; 

@Component({
  selector: 'app-review-prescription',
  templateUrl: './review-prescription.component.html',
  styleUrls: ['../../assets/css/prescriptionView.css'],
  providers:[
    CommonServices
  ]
})
export class ReviewPrescriptionComponent implements OnInit {
    constructor(
        private commonServices:CommonServices,
        private router:Router
        ){}
    ngOnInit(){
      window.onbeforeunload = function(event) {
        return 'By refreshing this page you may lost all data.';
      }
  }

}

Tried this on ngOnChanges(), ngOnInit(), ngOnDestroy()even outside the component class(sorry illogical) but nothing works?

在尝试这样做ngOnChanges()ngOnInit()ngOnDestroy()甚至外面的组件类(对不起不合逻辑),但没有什么作品?

I need solution in Angular or JavaScript not in jQuery.

我需要 Angular 或 JavaScript 而非 jQuery 的解决方案。

Thanks.

谢谢。

回答by Prithivi Raj

Try the below subscription to throw alert window on page refresh. do some user events like click over the page before trying to refresh or close the window. check the working version here

尝试以下订阅以在页面刷新时抛出警报窗口。在尝试刷新或关闭窗口之前执行一些用户事件,例如单击页面。在此处检查工作版本

see the official documentation on beforeunload

请参阅 beforeunload 上的官方文档

ngOnInit() {
    window.addEventListener("beforeunload", function (e) {
        var confirmationMessage = "\o/";
        console.log("cond");
        e.returnValue = confirmationMessage;     // Gecko, Trident, Chrome 34+
        return confirmationMessage;              // Gecko, WebKit, Chrome <34
    });
}

回答by Sabarish Vasudevan

You can try this.

你可以试试这个。

@HostListener('window:beforeunload', ['$event'])
beforeunloadHandler(event) {
    alert('By refreshing this page you may lost all data.');
}

Please be sure to include this inside the class.

请务必将其包含在类中。

回答by bertonc96

The solution depends on why you want to prevent the page reload. If you want to prevent it because there can be unsaved changes you have actually to prevent two different behaviours:

解决方案取决于您为什么要阻止页面重新加载。如果您想阻止它,因为可能存在未保存的更改,您实际上必须阻止两种不同的行为:

  1. Browser page reload. You can achieve this by creating an HostListener on the beforeunload event (similar to your attempt) like:
  1. 浏览器页面重新加载。您可以通过在 beforeunload 事件(类似于您的尝试)上创建一个 HostListener 来实现这一点,例如:
    @HostListener('window:beforeunload', ['$event'])
    beforeUnloadHander() {
        // or directly false
        this.allowRedirect;
    }
  1. Angular routing change (if you have routing): to do that you have to use a Deactivation guard on the route you want to lock, there are many ways but the most appreciated is the one that uses an interface implementation:
  1. 角度路由更改(如果您有路由):要做到这一点,您必须在要锁定的路由上使用 Deactivation Guard,方法有很多,但最值得赞赏的是使用接口实现的方法:

I. The interface sets up a couple of fields used in the angular guard to check if the we can change the router path:

I. 接口设置了几个用于角度保护的字段来检查我们是否可以更改路由器路径:


    import { Observable } from "rxjs";
    import { HostListener } from "@angular/core";

    // see https://scotch.io/courses/routing-angular-2-applications/candeactivate
    // implementing this interface with a component in angular you can implement a candeactivate
    // guard that automatically checks if there is the canDeactivate function and
    // it allows to navigate out of the route or not
    export default interface LockableComponent {
      allowRedirect: boolean;
      canDeactivate(): boolean;
    }

II. Each component has to implement this interface with the method canDeactivate or the allowRedirect field (reusable in the HostListener for the problem #1) and must returning a boolean that indicates if navigation is allowed or not.

二、每个组件都必须使用 canDeactivate 方法或 allowRedirect 字段(可在 HostListener 中针对问题 1 重用)来实现此接口,并且必须返回一个布尔值,指示是否允许导航。

III. Create a router guard that checks this component fields for the deactivation:

三、创建一个路由器防护,检查此组件字段的停用情况:

  canDeactivate(
    component: LockableComponent,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {
    if (
      (component.allowRedirect === false ||
        (component.canDeactivate && !component.canDeactivate()))
    ) {
      // Angular bug! The stack navigation with candeactivate guard
      // messes up all the navigation stack...
      // see here: https://github.com/angular/angular/issues/13586#issuecomment-402250031
      this.location.go(currentState.url);

      if (
        window.confirm("Sure man?")
      ) {
        return true;
      } else {
        return false;
      }
    } else {
      return true;
    }
  }

III. Set the canDeactivate router guard in your module.routing.ts file:

三、在 module.routing.ts 文件中设置 canDeactivate 路由器保护:

const myRoutes: Routes = [
      {
        path: "locked-route-path",
        component: ComponentThatImplementsLockedInterface,
        canDeactivate: [TheCanDeactivateGuardJustMade]
      }
      //...
]

回答by Bimal Das

I have done it using both RouteGuardand pure Javascriptcode to prevent browser close tab/back/close window.

我已经使用RouteGuard和纯Javascript代码完成了它,以防止浏览器关闭选项卡/后退/关闭窗口。

Component:

成分:

profileForm = this.fb.group({
  ClientName: ['', [Validators.required]]
});

@HostListener('window:beforeunload', ['$event']) beforeUnloadHander(event: any) {
     debugger
     var isFormDirty = document.getElementById('profileformStatus').innerText;
     console.log(isFormDirty);
     if(isFormDirty == 'true'){
       return false;
     }
     else{
       return true;
     }
   }

Component HTML:

组件 HTML:

<div id="profileformStatus">{{profileForm.dirty ? true:false}}</div>

Your Component Guard Service File(Optional):

您的组件保护服务文件(可选):

import { CanDeactivate } from "@angular/router";
import { Injectable } from "@angular/core";
import { YourComponent } from "./projects/your-component";
@Injectable()

export class YourComponentCanDeactivateGuardService
    implements CanDeactivate<YourComponent> {

    canDeactivate(component: YourComponent): boolean {
        if (component.profileForm.dirty) {
            return confirm('Are you sure you want to discard your changes?');
        }
        return true;
    }
}

Your Module: add The Above Guard(Optional)

你的模块:添加上面的守卫(可选)

@NgModule({
    providers: [YourComponentCanDeactivateGuardService]
})

Finally

最后

Update your routing module(Optional):

更新您的路由模块(可选):

const routes: Routes = [
    {
        path: 'detail/:id',
        component: YourComponent,
        canDeactivate: [YourComponentCanDeactivateGuardService]
    }
];

Done. Now it will prevent reload/back navigation both.

完毕。现在它将阻止重新加载/返回导航。

回答by Vuyyururajashekar Reddy

@HostListener("window:beforeunload", ["$event"]) unloadHandler(event: Event) {
      event.returnValue = false;
  }

回答by Terry Pitz

For this, you should create a Guard.

为此,您应该创建一个 Guard。

in your routing configuration file:

在您的路由配置文件中:

const routes: Routes = [
    {
        path: '',
        redirectTo: '/homePage',
        pathMatch: 'full'
    },
    {
        path: 'accueil',
        component: AccueilComponent,
        canDeactivate: [GuardName]
    }]

By doing this you're calling your guard on the selected component

通过这样做,您正在对所选组件进行保护

More informations Here

更多信息在这里

In your guard:

在你的保护下:

@Injectable()
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
  canDeactivate(component: CanComponentDeactivate) {
    return true/false;
  }
}