【问题标题】:How to prompt user when leaving the Angular 4 page if there are any changes made?如果进行了任何更改,如何在离开 Angular 4 页面时提示用户?
【发布时间】:2018-09-23 00:47:45
【问题描述】:

我的 Angular4 页面中有两个选项卡 (PrimeNg Tabview),其中包含许多输入字段,例如 textboxestextareasdropdowns 等。我还有一个侧面菜单栏可以导航到应用程序中的其他页面。我想如果这些输入字段中的数据有任何更改,那么如果用户尝试更改选项卡或使用侧面导航到其他页面,将会弹出消息(模式或确认框)菜单栏。

我已经尝试过ngOnDestroy() 方法。虽然此方法仅在页面关闭时触发(通过导航到其他页面或移动到下一个标签页),但它不允许您从方法中显示模式/确认框,因为它处于销毁生命周期挂钩.

请帮助我确定实际事件,如果页面/表单中的任何输入字段发生更改,我可以使用确认框提示用户。

@surjit 建议:

my-guard.service.ts

export interface CanComponentDeactivate {
    CanDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}

@Injectable()
export class CreateRequestGuardService implements CanDeactivate<CanComponentDeactivate> {
    canDeactivate(component: CanComponentDeactivate) {
        let vDeactivate = component.CanDeactivate ? component.CanDeactivate() : true;
        return vDeactivate;
    }   
}

my-component.ts 内:

import { CreateRequestGuardService } from './my-guard.service';

canDeactivate(): Observable<boolean> | boolean {
    console.log('I am moving away!');
    if (!this.isSaved) {
        const confirmation = window.confirm('Are you sure?');
        return Observable.of(confirmation);
    }
    else{
        return true;
    }
}

my-router.ts

import { CreateRequestGuardService } from './my-guard.service';

const allRoutes: Routes = [
   { path: 'save', component: my-component, canDeactivate: [MyGuardService]},
   { path ....},
   ..
]

【问题讨论】:

    标签: angular typescript primeng


    【解决方案1】:

    在要保护的组件路由中使用CanDeactivate 保护

    阅读CanDeactivate了解更多信息

    更新:这是我的伪代码。未经测试

    my-guard.service.ts:

    export interface CanComponentDeactivate {
        CanDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
    }
    
    @Injectable()
    export class CreateRequestGuardService implements CanDeactivate<CanComponentDeactivate> {
        canDeactivate(component: CanComponentDeactivate, 
                      currentRoute: ActivatedRouteSnapshot, 
                      currentState: RouterStateSnapshot, 
                      nextState?: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
            return component.canDeactivate(); //the function will be called on the component, that's why we'll implement the function on the component.
        }   
    }
    

    my-router.ts:

    import { CreateRequestGuardService } from './my-guard.service'; //the class name in my-guard.service.ts
    
    const allRoutes: Routes = [
       { path: 'save', component: myComponent, canDeactivate: [CreateRequestGuardService]},
       { path ....},
       ..
    ]
    

    my-component.ts

    import { CreateRequestGuardService } from './my-guard.service';
    
    export class myComponent implements CanComponentDeactivate { //implements the interface created on the guard service
    
        /*
            your component data
        */
        //implementation of canDeactivate
        canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
            if(form_is_edited && not_saved){
                return confirm("Discard Changes?");
            }
            else
                return true;
        }
    }
    

    注意:另外不要忘记将保护服务(类)添加到app.module.ts 文件中的providers 数组中。

    【讨论】:

    • 我尝试了 CanDeactivate 保护。但不知何故,我无法从组件内覆盖保护功能。下面我发布我的尝试
    • 如果我在服务中放置了一个 console.log,那么这个东西就会被打印出来。但是组件内部的 console.log 没有打印。表示未执行覆盖的函数 canDeactivate
    • 我的错……我犯了一个愚蠢的错误。我忘了在组件构造函数中提到implements CanComponentDeactivate。它的工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 2010-11-10
    • 2017-04-08
    • 1970-01-01
    • 2018-05-18
    • 2016-07-26
    • 2011-11-09
    相关资源
    最近更新 更多