最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to prevent page refresh in angular 4 - Stack Overflow

programmeradmin0浏览0评论

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

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.

Share Improve this question edited Nov 16, 2017 at 14:00 RajnishCoder asked Nov 16, 2017 at 13:43 RajnishCoderRajnishCoder 3,7257 gold badges21 silver badges36 bronze badges 8
  • 1 Could you add a bit more of your code please? – Quentin Albert Commented Nov 16, 2017 at 13:47
  • 6 You cannot prevent page refresh. The browser user can always hit F5. The "onbeforeunload" approach will allow you to warn the user, but you can't prevent it. – Pointy Commented Nov 16, 2017 at 13:47
  • 1 @Pointy you are right but even warning is not working. The problem is window.onbeforeunload is not working :( – RajnishCoder Commented Nov 16, 2017 at 13:51
  • 1 What do you mean "is not working"? Are there errors reported? Do you get the dialog from the browser? – Pointy Commented Nov 16, 2017 at 13:52
  • 1 stackoverflow.com/questions/35922071/… – Bekim Bacaj Commented Nov 16, 2017 at 14:22
 |  Show 3 more comments

8 Answers 8

Reset to default 13

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

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?";
}

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;
  }
}
发布评论

评论列表(0)

  1. 暂无评论