这是我的canDeactivate后卫,它的工作原理。但是当我使用提交按钮时,我不想打电话给警卫。只有当我通过任何其他方式导航时。怎么样?
import { Injectable } from '@angular/core';
import { Router, CanDeactivate } from '@angular/router';
import { FormGroup } from '@angular/forms';
export interface FormComponent {
myForm: FormGroup;
}
@Injectable()
export class DirtyGuard implements CanDeactivate<FormComponent> {
constructor(private router: Router) {}
canDeactivate(component: FormComponent) {
console.log(component.myForm)
if (component.myForm.dirty ){
return confirm('You have unsaved changes. Are you sure you want to navigate away?');
}
return true;
}
}
<button md-raised-button [disabled]="!myForm.valid" type="submit" color="primary">
<i class="material-icons">arrow_forward</i>
Exposures: Currencies
</button>
答案 0 :(得分:3)
[棱角v.4 - 在v.2上未经测试,但应该有效]
警卫可以停用&#39;正确调用,但您只想在您提交的方案中返回true,那么我们如何确定?您已经拥有FormGroup的句柄,但是这似乎没有与提交相关的属性。作为替代方法,您可以使用组件类中的@ViewChild装饰器获取表单句柄,如下所示:
<form #myForm="ngForm" (ngSubmit)="onSubmit()">
为了使其正常工作,您必须为表单添加一个局部变量,如下所示:
if (this.myForm.form.dirty && !this.myForm._submitted ){
return confirm('You have unsaved changes. Are you sure you want to navigate away?');
}
return true;
然后,您将在myForm对象上看到一个名为_submitted的属性。这允许您更新if条件,以便仅在脏&amp;&amp ;;时显示确认消息。 !提交。 e.g:
https://channel9.msdn.com/Events/Visual-Studio/Visual-Studio-2017-Launch/WEB-103
我假设您已经根据发布的日期解决了这个问题,但这可能有助于解释至少发生了什么。
答案 1 :(得分:0)
在我们的组件中,可以使用canDeactivate方法根据需要欺骗警报。
组件:
import { ComponentCanDeactivate } from './pending-changes.guard';
import { HostListener } from '@angular/core';
import { Observable } from 'rxjs/Observable';
export class MyComponent implements ComponentCanDeactivate {
@ViewChild('RegisterForm')
form: NgForm;
// @HostListener allows us to also guard against browser refresh, close, etc.
@HostListener('window:beforeunload')
canDeactivate(): Observable<boolean> | boolean {
// insert logic to check if there are pending changes here;
// returning true will navigate without confirmation
// returning false will show a confirm dialog before navigating away
return this.form.submitted || !this.form.dirty; // insert your code here for submit event
}
}
警卫:
import { CanDeactivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
export interface ComponentCanDeactivate {
canDeactivate: () => boolean | Observable<boolean>;
}
@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
// if there are no pending changes, just allow deactivation; else confirm first
return component.canDeactivate() ?
true :
// NOTE: this warning message will only be shown when navigating elsewhere within your angular app;
// when navigating away from your angular app, the browser will show a generic warning message
// see https://stackoverflow.com/questions/52044306/how-to-add-candeactivate-functionality-in-component
confirm('WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
}
}
路线:
import { PendingChangesGuard } from './pending-changes.guard';
import { MyComponent } from './my.component';
import { Routes } from '@angular/router';
export const MY_ROUTES: Routes = [
{ path: '', component: MyComponent, canDeactivate: [PendingChangesGuard] },
];
模块:
import { PendingChangesGuard } from './pending-changes.guard';
import { NgModule } from '@angular/core';
@NgModule({
// ...
providers: [PendingChangesGuard],
// ...
})
export class AppModule {}
答案 2 :(得分:0)
我假设您在用户点击“提交”按钮后便离开了。表单有效时,禁用can deactivate防护的问题是,在表单完全填写完毕而失去所有工作后,用户可能会意外按下“取消/返回”按钮等。换句话说,仅因为表单有效,并不表示您想停用can-deactivate防护。
如果要导航,可以在路线导航之前在onSubmit函数中将属性设置为“ true”,并在保护逻辑中使用它。
组件 (反应形式)
export class MyComponent {
// ..
submitSuccess: boolean;
canDeactivate(): boolean | Observable<boolean> | Promise<boolean> {
if (!this.inputForm.dirty || this.submitSuccess ) {
return true;
}
return this.confirmDialogService.confirm('Discard changes?');
}
// ...
onSubmit() {
this.submitSuccess = true;
this.router.navigate(['my-page']);
}
}
确认对话框服务
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ConfirmationDialogService {
/**
* Ask user to confirm an action. `message` explains the action and choices.
* Returns observable resolving to `true`=confirm or `false`=cancel
*/
confirm(message?: string): Observable<boolean> {
const confirmation = window.confirm(message || 'Are you sure? Your changes
will be lost.');
return of(confirmation);
}
}
可以停用防护功能
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable({
providedIn: 'root',
})
export class CanDeactivateGuard implements
CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
路线
\\ ...
children: [
{ path: 'my-path', component: MyComponent, canDeactivate:
[CanDeactivateGuard] },
]},
// ..
希望有帮助!
答案 3 :(得分:0)
回答晚了,但可能会有所帮助。如果表单已提交并且我们希望将用户导航到另一条路线,则在导航之前重置表单。
前 -
this.service.addUser(this.userForm).subscribe((res) => {
this.addUser.reset();
this.router.navigate(['/link to another page']);
});