Angular 5,CanDeactivate使用自定义模式命中一次

时间:2018-04-11 21:11:30

标签: angular observable angular-routing

目前正在运行角度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);

问题是模态在路线变化时显示一次,并且再也不会出现,无论我在模态中选择什么,它只是关闭而没有路线。我不是100%肯定我这样做是对的,所以我的方法可能完全错误。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

您违反了Tell-Don't-Ask原则。父组件应该不知道子组件模态实现。您应该告诉它打开模态,并让它自己处理实现。

  

Tell-Don't-Ask是一个原则,可以帮助人们记住,面向对象是将数据与对该数据进行操作的函数捆绑在一起。它提醒我们,不是要求对象获取数据并对数据进行操作,而是应该告诉对象该做什么。

此外,您不需要将promises与observable混合使用。坚持使用简单的基于承诺的解决方案。

<强> 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;
}