如何防止角度4中的页面刷新

时间:2017-11-16 13:43:29

标签: javascript angular angular-routing

我想在任何地方阻止页面刷新。

我尝试了以下代码

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.';
      }
  }

}

尝试在ngOnChanges()ngOnInit()ngOnDestroy()甚至在组件类之外(抱歉不合逻辑),但没有任何作用?

我需要Angular或JavaScript中的解决方案而不是jQuery。

感谢。

6 个答案:

答案 0 :(得分:5)

尝试以下订阅,在页面刷新时抛出警报窗口。在尝试刷新或关闭窗口之前,请执行一些用户事件,例如单击页面。 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
});

  }

答案 1 :(得分:5)

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

答案 2 :(得分:0)

你可以试试这个。

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

请务必在课堂内加入此内容。

答案 3 :(得分:0)

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

  1. 浏览器页面重新加载。您可以通过在beforeunload事件(类似于您的尝试)上创建HostListener来实现此目的,例如:
    @HostListener('window:beforeunload', ['$event'])
    beforeUnloadHander() {
        // or directly false
        this.allowRedirect;
    }
  1. 角度路由更改(如果有路由):为此,您必须在要锁定的路由上使用停用保护,有很多方法,但最受赞赏的是使用接口实现的方法:

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。每个组件都必须使用canDeactivate或allowRedirect字段(可在问题#1在HostListener中重用)方法实现此接口,并且必须返回一个布尔值,该布尔值指示是否允许导航。

III。创建一个路由器防护,检查此组件字段是否停用:

  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。在module.routing.ts文件中设置canDeactivate路由器防护:

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

答案 4 :(得分:0)

  

我已经使用 RouteGuard 和纯 JavaScript 代码来完成此操作,以防止浏览器关闭选项卡/返回/关闭窗口。

组件:

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

组件HTML:

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

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

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

您的模块:添加“守卫者”(可选)

@NgModule({
    providers: [YourComponentCanDeactivateGuardService]
})

最后

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

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

完成。现在,这将同时防止重新加载/向后导航。

答案 5 :(得分:-1)

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

路由配置文件中的

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

通过这样做,你可以在所选组件上调用你的警卫

更多信息Here

在你的警卫中:

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