Angular2路由器的navigateByUrl()没有调用ngOnInit()

时间:2016-06-23 09:58:02

标签: angular angular2-routing

我在同一页面上有两个Angular迷你应用程序。 (很长的故事。)一个是导航应用程序,一个是主应用程序。我正在使用最新的Angular路由器,基于angular/vladivostok

似乎一个应用程序(例如,nav)中的Angular路由器不响应由另一个应用程序(例如,主应用程序)实例化的URL更改。所以我创建了一个RouterSynchronizer 1 类,我提供给两个应用程序。它会侦听两个路由器的NavigationEnd事件。当一个路由器(让我们称之为“源”)有一个事件时,它会在另一个路由器上调用navigateByUrl(让我们称之为“用户”)。

这在大多数情况下都可以正常工作。但是,它不会在订阅者的组件上调用ngOnInit

我已根据Angular官方a Plunk的实际示例创建了Routing & Navigation guide来证明这一点。请注意,当您单击主应用程序中的“危机中心”和“英雄”链接时,不会在导航组件中的相应子组件上调用ngOnInit。但是,当您单击导航组件中的这些链接时,在这些子组件上调用ngOnInit ,而在主应用程序的子组件上调用 (导致英雄/危机中心名单空白。

有什么想法吗?谢谢!

1 RouterSynchronizer上课:

import { Inject } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';

interface ISubscriber {
  id: string;
  router: Router;
}

export class RouterSynchronizer {
  private subscribers: ISubscriber[] = [];

  connect(id: string, router: Router): void {
    this.subscribers.push({ id, router });
    this.startPublishing(id, router);
  }

  private startPublishing(source: string, router: Router): void {
    router.events.subscribe(route => {
      if (route instanceof NavigationEnd) {
        this.subscribers.forEach(subscriber => {
          if (subscriber.id === source || subscriber.router.url === route.urlAfterRedirects) {
            // Prevent infinite loops.
            return;
          }

          subscriber.router.navigateByUrl(route.urlAfterRedirects);
        });
      }
    });
  }
}

2 个答案:

答案 0 :(得分:3)

我明白了!显然,我需要使用一个区域。有关实施,请参阅the new Plunk

问题(我认为!)是我的RouterSynchronizer类被实例化并在Angular上下文之外提供。因此,当它通过navigateByUrl将更改推送到路由器时,它不在Angular区域中。我将navigateByUrl电话打包到应用提供的区域后,就可以了:)

答案 1 :(得分:-1)

你必须像这样实现OnInit:

import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'nav-heroes',
    template: `<span *ngIf="hasRunOnInit">ngOnInit has run in NavCrisisCenterComponent</span>`,
})

export class NavCrisisCenterComponent implements OnInit {
    private hasRunOnInit: boolean;

    ngOnInit() {
    this.hasRunOnInit = true;
}
}