简体   繁体   中英

How to prevent page refresh in angular 4

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?

I need solution in Angular or JavaScript not in jQuery.

Thanks.

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

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
    });
}
@HostListener("window:beforeunload", ["$event"]) unloadHandler(event: Event) {
      event.returnValue = false;
  }

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:
    @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:

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


    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.

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:

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

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.

I have done it using both RouteGuard and pure Javascript code to prevent browser close tab/back/close window.

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:

<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.

All the previous answers contains this code, but we need to add a statement to prevent the default behaviour.

event.preventDefault()

@HostListener("window:beforeunload", ["$event"])
unloadHandler(event) {
    event.preventDefault();
    return event.returnValue = "Are you sure you want to exit?";
}

I have been looking for a perfect solution for this but there was none of them was perfect.

I have created a solution for this and you can see the full code here. Prevent reload without saving

Code example: https://github.com/mukeshsalaria01/angular-show-alert-on-page-reload-without-saving-example

For this, you should create a 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;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM