【问题标题】:How to prevent page refresh in angular 4如何防止 Angular 4 中的页面刷新
【发布时间】:2017-11-16 13:43:28
【问题描述】:

我想防止到处刷新页面。

我试过下面的代码

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 的解决方案。

谢谢。

【问题讨论】:

  • 你能多加一点你的代码吗?
  • 您无法阻止页面刷新。浏览器用户总是可以按 F5。 “onbeforeunload”方法可以让你警告用户,但你不能阻止它。
  • @Pointy 你是对的,但即使警告也不起作用。问题是window.onbeforeunload 不工作:(
  • “不工作”是什么意思?是否报告了错误?您是否从浏览器中获取对话框?

标签: javascript angular angular-routing


【解决方案1】:

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

【讨论】:

  • 这对你真的有用吗?当我刷新页面时,至少在 chrome 中没有发生任何事情。
  • 提示:在卸载前“查看”官方文档
【解决方案2】:
@HostListener("window:beforeunload", ["$event"]) unloadHandler(event: Event) {
      event.returnValue = false;
  }

【讨论】:

    【解决方案3】:

    你可以试试这个。

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

    请务必将其包含在课程中。

    【讨论】:

    【解决方案4】:

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

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

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

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

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

    三。创建一个路由器守卫,检查此组件字段是否停用:

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

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

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

    【讨论】:

    • 这是我看到的最干净的。虽然对于一些非常简单的应用程序可能有点矫枉过正,但这种技术是最模块化和可重用的技术。
    【解决方案5】:

    为此,您应该创建一个 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;
      }
    }
    

    【讨论】:

    • 这真的不是 Angular 问题;这是浏览器的基本行为。
    • 那应该是误解了他的问题
    • 我猜你收到了反对票,因为守卫根本不起作用(刷新浏览器)。
    【解决方案6】:

    我已经使用 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;
        }
    }
    

    您的模块:添加 The Above Guard(可选)

    @NgModule({
        providers: [YourComponentCanDeactivateGuardService]
    })
    

    终于

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多