Angular 5、CanDeactivate 用自定义模态点击一次
Angular 5, CanDeactivate hitting once with custom modal
目前运行 angular 5
在我们的其中一个页面上,我们想要一个停用防护装置,这样如果页面上的某个条件得到满足(他们开始测试)并且他们试图在不保存的情况下导航离开,他们会看到一个自定义模式(一个 p-来自 primeNG 容器的对话框自定义对话框)。
这是我们的停用服务:
@Injectable()
export class DeactivateUnsavedChangesService implements
CanDeactivate<any> {
constructor() { }
canDeactivate(
component: any,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
return component.confirm() ;
}
}
父组件确认方法如下:
confirm() {
return new Promise<boolean>(resolve => {
const subject = new Subject<boolean>();
this.dcComponent.displayExitModal = true;
this.dcComponent.subject = subject;
return subject.asObservable();
});
}
我正在通过 ViewChild
访问子组件(包含模态本身的组件)
@ViewChild (DynamicClassroomComponent) dcComponent: DynamicClassroomComponent;
在模板中,我将 'subject' 绑定到子组件的输入字段。在该子组件中,我将其绑定到模态本身,以便它可以执行以下操作之一:
this.subject.next(true);
或
this.subject.next(false);
问题是模式在路线更改时显示一次,再也不会显示,无论我在模式中 select 是什么,它都会关闭并且不会采用任何路线。我不是 100% 确定我这样做是对的,所以我的方法可能完全不正确。任何帮助,将不胜感激。谢谢!
你违反了Tell-Don't-Ask
原则。父组件应该不知道子组件模态实现。你应该告诉它打开模式,让它自己处理实现。
Tell-Don't-Ask is a principle that helps people remember that object-orientation is about bundling data with the functions that operate on that data. It reminds us that rather than asking an object for data and acting on that data, we should instead tell an object what to do.
此外,您不需要将 promises 与 observables 混合使用。坚持使用基于承诺的简单解决方案。
parent.component.ts
confirm(): Promise<boolean> {
return new Promise((resolve, reject) => this.child.showModal(resolve, reject));
}
child.component.ts
resolve: Function;
reject: Function;
showModal(resolve: Function, reject: Function) {
this.show = true;
this.resolve = resolve;
this.reject = reject;
}
onDismiss() {
this.reject();
this.show = false;
}
onConfirm() {
this.resolve();
this.show = false;
}
目前运行 angular 5 在我们的其中一个页面上,我们想要一个停用防护装置,这样如果页面上的某个条件得到满足(他们开始测试)并且他们试图在不保存的情况下导航离开,他们会看到一个自定义模式(一个 p-来自 primeNG 容器的对话框自定义对话框)。
这是我们的停用服务:
@Injectable()
export class DeactivateUnsavedChangesService implements
CanDeactivate<any> {
constructor() { }
canDeactivate(
component: any,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
return component.confirm() ;
}
}
父组件确认方法如下:
confirm() {
return new Promise<boolean>(resolve => {
const subject = new Subject<boolean>();
this.dcComponent.displayExitModal = true;
this.dcComponent.subject = subject;
return subject.asObservable();
});
}
我正在通过 ViewChild
访问子组件(包含模态本身的组件)@ViewChild (DynamicClassroomComponent) dcComponent: DynamicClassroomComponent;
在模板中,我将 'subject' 绑定到子组件的输入字段。在该子组件中,我将其绑定到模态本身,以便它可以执行以下操作之一:
this.subject.next(true);
或
this.subject.next(false);
问题是模式在路线更改时显示一次,再也不会显示,无论我在模式中 select 是什么,它都会关闭并且不会采用任何路线。我不是 100% 确定我这样做是对的,所以我的方法可能完全不正确。任何帮助,将不胜感激。谢谢!
你违反了Tell-Don't-Ask
原则。父组件应该不知道子组件模态实现。你应该告诉它打开模式,让它自己处理实现。
Tell-Don't-Ask is a principle that helps people remember that object-orientation is about bundling data with the functions that operate on that data. It reminds us that rather than asking an object for data and acting on that data, we should instead tell an object what to do.
此外,您不需要将 promises 与 observables 混合使用。坚持使用基于承诺的简单解决方案。
parent.component.ts
confirm(): Promise<boolean> {
return new Promise((resolve, reject) => this.child.showModal(resolve, reject));
}
child.component.ts
resolve: Function;
reject: Function;
showModal(resolve: Function, reject: Function) {
this.show = true;
this.resolve = resolve;
this.reject = reject;
}
onDismiss() {
this.reject();
this.show = false;
}
onConfirm() {
this.resolve();
this.show = false;
}