Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度CanDeactivate防护罩不能与MatDialog一起正常工作_Javascript_Angular_Candeactivate - Fatal编程技术网

Javascript 角度CanDeactivate防护罩不能与MatDialog一起正常工作

Javascript 角度CanDeactivate防护罩不能与MatDialog一起正常工作,javascript,angular,candeactivate,Javascript,Angular,Candeactivate,我用CanDeactivate创建了一个route guard,它确定用户如果有任何未保存的更改,是否可以离开页面,如果存在任何未保存的更改,则触发MatDialog模式。我已经看过很多指南和类似的线程,我的代码正在运行(大部分)。见下文: 这是route guard,它调用组件的confirmRouteChange函数(如果有),并返回结果,即一个可观察的: 下面是my modal的保存/关闭选项的实现: save() { this.dialogRef.close(false)

我用CanDeactivate创建了一个route guard,它确定用户如果有任何未保存的更改,是否可以离开页面,如果存在任何未保存的更改,则触发MatDialog模式。我已经看过很多指南和类似的线程,我的代码正在运行(大部分)。见下文:

这是route guard,它调用组件的confirmRouteChange函数(如果有),并返回结果,即一个可观察的

下面是my modal的保存/关闭选项的实现:

save() {
        this.dialogRef.close(false);
    }

    close() {
        this.dialogRef.close(true);
    }
所以我的问题是:当我导航离开未保存的更改时,会弹出模式(很棒),应用程序会根据模式中选择的选项正确导航(很棒);然而,在模式的后面,我可以看到我的应用程序的其余部分都离开了页面,除了放置route guard的组件。因此,如果我试图导航到主页,我可以看到所有的主页和组件与我的未保存的更改形式。就好像它开始导航,停止,然后等待用户的响应。如果我使用本机的
confirm()
对话框,它工作得非常好,这意味着应用程序在等待用户响应时会有效地冻结。我相信这是因为如果我记录
confirm()
返回的内容,则在用户选择某个内容之前,它不会返回任何内容。另一方面,
dialogRef.afterClosed()
立即返回可观察到的内容,我猜这会触发导航,然后应用程序停止并等待用户的响应

我认为模态的用法有问题,但我不确定是什么。非常感谢您的帮助


编辑:我认为
return dialogRef.afterClosed()
语句在对话框完成打开之前执行,导致导航启动然后停止。

这正是您描述它的方式

你的路线卫兵期望立即正确或错误。它不能处理可观察的事物

所以我的建议是做以下几点

首先

当组件变脏时,请进行检查,但直接返回false,以便路由保护防止重新路由。构建一个服务,该服务存储新路由并包含一个名为的字段,例如,
reroutingAllowed
。这最初设置为
false

canDeactivate(component: DirtyComponent): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return component?.isDirty();
}

confirmRouteChange() {
    // here we already take the new field into account
    if (this.isDirty && !reroutingAllowed) {
        let dialogRef = this.matDialog.open(AlertModalComponent, {
            data: {
                msg: 'Your changes have not been saved. If you leave this page, your changes will be lost.',
                title: 'Changes have not been saved',
                class: 'save-changes'
            }
        });

        // directly return false
        return false;
    } else {
        return true;
    }
}
canDeactivate(组件:DirtyComponent):可观察的|承诺|布尔| UrlTree{
返回组件?.isDirty();
}
确认路由更改(){
//在这里,我们已经考虑了新字段
if(this.isDirty&!重路由){
让dialogRef=this.matDialog.open(AlertModalComponent{
数据:{
msg:“您的更改尚未保存。如果您离开此页面,您的更改将丢失。”,
标题:“更改尚未保存”,
类:“保存更改”
}
});
//直接返回false
返回false;
}否则{
返回true;
}
}

Momorize并行化用户希望在您的服务中到达的新路由目标,以便在用户在模式对话框中遇到决策时能够访问它

第三

等待用户回答该对话框。如果他想离开当前页面,将变量
reroutingAllowed
设置为
true
,并触发角度路由器再次调用新的路由目标

这一次,守卫将允许用户通过事件,尽管表单仍然脏

您只需考虑如何设置上述服务,以及如何获取和记忆新的路线目标。

我发现另一个与我的实现类似。这对他们有效,他们返回了一个可观察到的,就像我一样。我不知道为什么它不能100%正常工作。我试试你的解决办法。谢谢
save() {
        this.dialogRef.close(false);
    }

    close() {
        this.dialogRef.close(true);
    }
canDeactivate(component: DirtyComponent): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return component?.isDirty();
}

confirmRouteChange() {
    // here we already take the new field into account
    if (this.isDirty && !reroutingAllowed) {
        let dialogRef = this.matDialog.open(AlertModalComponent, {
            data: {
                msg: 'Your changes have not been saved. If you leave this page, your changes will be lost.',
                title: 'Changes have not been saved',
                class: 'save-changes'
            }
        });

        // directly return false
        return false;
    } else {
        return true;
    }
}