Angular 2 canDeactivate并不总是路由

时间:2017-01-05 18:10:06

标签: angular routes promise

我有一个带有取消按钮的组件。当它被击中时,gotoParent()被调用:

canDeactivate(): Promise<boolean> | boolean {
  return this.dialogService.confirm('Discard changes?');
}

private gotoParent() {
  let orgId = this.org ? this.org.id : -1;
  this.router.navigate(['../', { id: orgId }], { relativeTo: this.route });
  console.info("orgId: " + orgId);
}

cancel() {
  this.gotoParent();
}

因为我为路线I(通常)实施了停用防护,所以看到一个对话框:

@Injectable()
export class DialogService {
  confirm(message?: string) {
    return new Promise<boolean>(resolve => {
      return resolve(window.confirm(message || 'Is it OK?'));
    });
  };
}

我的问题是这个工作一次。如果我第二次单击组件取消我没有响应 - 没有对话框。组件“保存”按钮也不起作用。

当我跟踪我的代码时,我看到router.navigate()正在执行 - console.info()就在那里我可以设置一个断点 - 但是对话框没有出现,应用程序也没有导航

此时我可以点击一些“主”按钮转到应用程序的根目录。然后我再次得到那个对话框。如果我单击对话框的此对话框的取消,那么它也会停止工作。

应该出现的对象取消应该让我进入当前组件显示,准备好再次显示对话框。

这在原始教程中有效,但在我为自己的目的改变了东西后却没有。有人对我有线索吗?

谢谢, 杰罗姆。

编辑:回复YairTawil需要的空间超出评论所能提供的空间。

这是我插入事件监听器后的事件。

从全局菜单导航到edit-org:

event =  NavigationEnd {id: 4, url: "/provider/edit-org", urlAfterRedirects: "/provider/edit-org"}

点击组件取消:

event =  NavigationStart {id: 5, url: "/provider;id=12"}
org-detail.component.ts:67 event =  RoutesRecognized {id: 5, url: "/provider;id=12", urlAfterRedirects: "/provider;id=12", state: RouterStateSnapshot}

(id = 12是告诉父母哪个ID工作的教程技巧。)

点击对话框取消:

org-detail.component.ts:67 event =  NavigationCancel {id: 5, url: "/provider;id=12", reason: ""}

返回组件。

再次单击组件“取消”。没有事件。单击组件保存。没有事件。

点击全局菜单选项“提供商”会产生以下事件:

event =  RoutesRecognized {id: 6, url: "/provider", urlAfterRedirects: "/provider", state: RouterStateSnapshot}
org-detail.component.ts:67 event =  NavigationCancel {id: 6, url: "/provider", reason: ""}

单击对话框后取消全局菜单提供程序不再有效。好像有什么东西要清除或重置。

可以通过交替单击组件取消,对话框取消,然后是全局菜单提供程序按钮,然后单击取消,然后重复,可靠地获取事件。但是,对组件按钮集合的连续单击,例如(组件取消,对话框取消,然后组件取消)不会产生第二个对话框外观。

还有什么想法?

杰罗姆。

2 个答案:

答案 0 :(得分:1)

我做了很多调试,比较了逐步剥离的程序版本和Angular 2“Routing”教程(来自Plunker)。过了一会儿,我意识到两者之间的代码是相同的,但我得到了不同的结果。答案不会出现在app目录中。

我得到了index.html(我的Gulp文件将index-jit.html拷贝到那里),发现一些包含Javascript影响了我的结果。我不明白为什么这是“修复”,但更改一些Javascript包含文件对我有用。

我的index.html包含了这些文件并调用了导入:

<div class="header">header</div>
<div class="main">main</div>
<div class="footer">footer</div>

Plunker的Angular 2教程改为:

<!-- IE required polyfills, in this exact order -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>

<script>
  System.import('system-config.js')
  .then(function() { System.import('main'); })
  .catch(function(err){ console.error(err); });
</script>

当我进行替换时,我的程序现在按预期工作。每次单击组件取消按钮都会给我一个对话框,对话框取消将我返回到组件。

感谢大家的聆听。

杰罗姆。

答案 1 :(得分:0)

angular2路由器在开始导航时会发送一系列事件:

  • navigationStart
  • navigationError,
  • navigationCancel,
  • navigationEnd ....

当CanDeactivate得到&#39; false&#39; navigationCancel事件应该发送。

您可以关注路由器事件:

  import {Router} from "@angular/router";
  export class MyClass{
  constructor( private router:Router ) {
    this.router.events.subscribe(event => {
      console.log("event = ",event) 
      ... search what happend with your navigation
    }
  }

}