如何使用angular2材质对话框阻止canDeactivate

时间:2017-07-22 06:13:19

标签: angular angular-material angular2-routing

如果用户从具有脏表单的页面导航,我成功使用canDeactivate提供警告消息:

我正在使用的代码在这里:

    is_submit = false;
   canDeactivate() {
       //https://scotch.io/courses/routing-angular-2-applications/candeactivate
        if (this.myForm.dirty == true && this.is_submit==false){
            return window.confirm('Discard changes?');
        } //end if
        return true
    } // end  canDeactivate

这是我获得代码的地方:

https://scotch.io/courses/routing-angular-2-applications/candeactivate

但是我想使用angular2对话框。这是我的代码:

    //ts for the main component

    is_submit = false;
   canDeactivate() {
        if (this.myForm.dirty == true && this.is_submit==false){
            const config = new MdDialogConfig();
            config.disableClose=true;
            let dialogRef = this.dialog.open(DialogCanDeactive,config);
            dialogRef.afterClosed().subscribe(result => {
                if (result=='cancel'){
                    return false;
                } 
                if (result=='save'){
                    return true;
                } 
                if (result=='discard'){
                    return true;
                } 
            }); //end dialogRef
        } //end if
        return true
    }

 ///Code for the dialog

@Component({
  selector: 'can_deactive_dialog',
  template: `
<div>
    <button md-raised-button (click)="dialogRef.close('cancel')">Cancel</button>
    <button md-raised-button (click)="dialogRef.close('save')">Save Changes</button>
    <button md-raised-button (click)="dialogRef.close('discard')">Discard Changes</button>
</div>
`,
})
export class DialogCanDeactive {


  constructor(public dialogRef: MdDialogRef<DialogCanDeactive>) {} //end constructor

}

当我离开时会发生什么:

1)我转到浏览页面

2)然后对话显示..

如何使用以下代码的Dialog块?

    window.confirm('Discard changes?')

3 个答案:

答案 0 :(得分:11)

canDeactivate 方法也可以返回Promise或Observable。你应该返回它并解析promise或在observable上发出一个你想要的结果的值。

在您的具体示例中,您可以从 afterClosed 方法返回observable,而不是订阅它,只需将其映射到布尔值:

return dialogRef.afterClosed().map(result => {
                if (result=='cancel'){
                    return false;
                } 
                if (result=='save'){
                    return true;
                } 
                if (result=='discard'){
                    return true;
                } 
            }).first();

此外,我会从守卫中移出这个逻辑,例如在组件中,并从那里调用一个方法。

答案 1 :(得分:1)

 Nothing more just do it

**Guard**

import { Injectable } from '@angular/core';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } 
from '@angular/router';
import { Observable} from 'rxjs';
import { ExampleComponent } from '../components/example.component';
import { MatDialog } from '@angular/material/dialog'; 

@Injectable({
  providedIn: 'root'
})
export class ConfirmationDeactivateGuard implements CanDeactivate<ExampleComponent> {
  constructor(private dialog: MatDialog,
    private router: Router){}
    canDeactivate(
      component: ExampleComponent,
      route: ActivatedRouteSnapshot,
      state: RouterStateSnapshot
    ): Observable<boolean> {
      return component.confirmationOnRouteChange();
  }
}

**In Your Component** //ExampleComponent.component.ts

confirmationOnRouteChange() {
        const message = "Do you want to Leave ?"
        const dialogRef = this.matDialog.open(ConfirmationComponent,{
            width: '400px',
            data: { message }
        })
        return dialogRef.afterClosed();
    }

答案 2 :(得分:0)

RXJS 6+的更新版本:

return dialogRef.afterClosed().pipe(map(result => {
    if (result === 'cancel') {
        return false;
    }
    if (result === 'save') {
        return true;
    }
    if (result === 'discard') {
        return true;
    }
}), first());

请参阅https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md

尤其是:https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md#howto-convert-to-pipe-syntax