ActivatedRoute不会在路线更改时更新子路线数据

时间:2019-11-03 15:52:51

标签: angular angular-routing angular8 angular-activatedroute

我想使用ActivatedRoute从父组件获取子路由数据(“布局”)。我尝试了以下示例,但仅一次可以获取所需的数据。在更改子路线时,我看不到更新的“布局”值。

路线

const routes: Routes = [
  {
    path: '',
    component: Layout1Component,
    children: [
      {
        path: '',
        redirectTo: 'home',
        pathMatch: 'full'
      },
      {
        path: 'home',
        loadChildren: './pages/analytics/analytics.module#AnalyticsModule',
        data: {
          layout: 'boxed'
        }
      },
      {
        path: 'files',
        loadChildren: './pages/files/files.module#FilesModule',
        data: {
          layout: 'full'
        }
      }
    ]
  }
];

Layout1Component

export class Layout1Component implements OnInit {
  constructor(private service: AppService, route: ActivatedRoute) {
    this.layout = route.snapshot.firstChild.data['layout'];

    route.url.subscribe(() => {
      console.log(route.snapshot.firstChild.data['layout']);
    });
  }
}

我希望每次更改路线时都用更新的“布局”值打印console.log。

请帮助我解决此问题。

2 个答案:

答案 0 :(得分:1)

根据我的理解,您只获取一次数据的原因是因为ActivatedRoute在实例化时将url作为 BehaviorSubject 获得。

function createActivatedRoute(c: ActivatedRouteSnapshot) {
  return new ActivatedRoute(
      new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams),
      new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
}

Here's the link for the above snippet

这意味着您订阅时,只会获得该第一个存储的值。

一种解决方法是利用路由器事件

假设您有类似这样的内容:

const routes: Route[] = [
  { 
    path: '', 
    component: HelloComponent,
    children: [
      {
        path: 'foo',
        loadChildren: () => import('path/to/foo').then(m => m.FooModule),
        data: {
          name: 'andrei'
        }
      },
      {
        path: 'bar',
        loadChildren: () => import('path/to/bar').then(m => m.BarModule),
        data: {
          name: 'john'
        }
      },
    ]
  },
]

这是一个可能的解决方案:

 constructor (private router: Router, private route: ActivatedRoute) { }

 ngOnInit () {
    const routeEndEvent$ = this.router.events
      .pipe(
        filter(e => e instanceof NavigationEnd),
        tap(() => console.warn("END")),
    );

    this.router.events
      .pipe(
        filter(e => e instanceof ChildActivationEnd && e.snapshot.component === this.route.component),
        buffer(routeEndEvent$),
        map(([ev]) => (ev as ChildActivationEnd).snapshot.firstChild.data),
        takeUntil(this.ngUnsubscribe$)
      )
      .subscribe(childRoute => {
        console.log('childRoute', childRoute);
      })
  }
  • routeEndEvent$是可观察到的,只有在路由准备就绪(NavigationEnd)时才会发出

  • filter(e => e instanceof ChildActivationEnd && e.snapshot.component === this.route.component):检查了路由器发出的事件一会儿之后,我到达了此解决方案,以确定组件(HelloComponent)是否为父(this.route.component)。更改的路线({e.snapshot.component)。

  • buffer(routeEndEvent$):我们只想在路由器达到其最终状态(NavigationEnd)时采取措施。 here,您可以详细了解buffer运算符

StackBlitz

答案 1 :(得分:0)

我遇到了同样的问题,当我订阅了 ActivatedRoute 的“data”属性时,这个问题得到了解决。下面是一个例子。

组件:

constructor (private route: ActivatedRoute)  {
        this.route.data.subscribe(({ listData }) => {
        this.listData = listData
    })
}

路线:

{
    path: ':id',
    component: Component,
    resolve: {
        listData: ModuleService
    }
},