可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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
});
}
回答2:
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.
回答3:
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:
- 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;
}
- 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]
}
//...
]
回答4:
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.
回答5:
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;
}
}