5

を使用して、親コンポーネントから子ルート データ (「レイアウト」) を取得しようとしています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 が出力されるようにします。

これを修正するのを手伝ってください。

4

2 に答える 2

7

私の理解では、データを一度だけ取得する理由は、インスタンス化されたときにBehaviorSubjectとしてActivatedRoute取得するためです。url

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

上記のスニペットのリンクは次のとおりです

これは、サブスクライブすると、最初に保存された値のみが取得されることを意味します。

これを解決する 1 つの方法は、ルーター イベントを利用することです。

次のようなものがあるとします。

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.componente.snapshot.component

  • buffer(routeEndEvent$): ルーターが最終状態 ( ) に達したときにのみ動作する必要がありますNavigationEndここでbuffer、オペレーターについて詳しく読むことができます

スタックブリッツ

于 2019-11-03T22:10:09.270 に答える