首页 文章

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

提问于
浏览
2

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

看起来一个app(例如,nav)中的Angular路由器不响应由另一个app(例如,主app)实例化的URL改变 . 所以我创建了一个我提供给两个应用程序的 RouterSynchronizer 1类 . 它侦听两个路由器的 NavigationEnd 事件 . 当一个路由器(让我们称之为"source")有一个事件时,它在另一个路由器上调用 navigateByUrl (我们称之为"subscriber") .

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

我已经创建了a Plunk来演示这个,基于Angular的官方Routing & Navigation guide的实例 . 请注意,当您单击主应用程序中的"Crisis Center"和"Heroes"链接时,不会在导航组件中的相应子组件上调用 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 回答

  • -1

    我想到了!显然,我需要使用一个区域 . 请参阅the new Plunk以了解实施情况 .

    问题(我想!)是我的 RouterSynchronizer 类被实例化并在Angular上下文之外提供 . 因此,当它通过 navigateByUrl 将更改推送到路由器时,它不在Angular区域中 . 一旦我将 navigateByUrl 呼叫包裹在应用程序提供的区域中,它就有效了:)

  • 3

    你必须像这样实现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;
    }
    }
    

相关问题