【问题标题】:Angular - Get Route data in app componentAngular - 在应用程序组件中获取路由数据
【发布时间】:2020-02-17 20:05:33
【问题描述】:

我在app-routing.module.ts中配置了以下路由

const routes: Routes = [
  {
    path: 'abc/:id', component: AbcComponent, data: { category: 'Public' }
  },
  {
    path: 'xyz/:id/tester/:mapId', component: XyzComponent, data: { category: 'Private' }
  },
  { path: '**', redirectTo: '/page-not-found', pathMatch: 'full'}
]

app.component.ts我想根据传递的URL获取每个Route的类别:

例如:转到http://myapp.com/abc/123 应返回类别为Publichttp://myapp.com/xyz/123/tester/456 应该返回类别为Private

这是我目前所拥有的:

constructor(
    private activatedRoute: ActivatedRoute,
    private router: Router
)
{
  checkRouteAndGetCategory()
}

checkRouteAndGetCategory()
{
  this.router.events.pipe(
        filter(event => event instanceof NavigationEnd),
        map(() => this.activatedRoute),
        map(route => {
          while (route.firstChild) route = route.firstChild
          return route
        }),
        filter(route => route.outlet === 'primary'),
        mergeMap(route => route.data)
      ).subscribe(data =>
        console.log('data', data)
      )
}

上面的代码似乎没有找到正确的路线。例如:如果我在http://myapp.com/abc/123 页面上并导航到http://myapp.com/xyz/123/tester/456,它似乎获得了http://myapp.com/abc/123 页面的数据。

【问题讨论】:

    标签: angular typescript angular-routing


    【解决方案1】:

    我会考虑将其转移到服务中,例如 CategoryService

    分类服务

    import { Injectable } from '@angular/core';
    import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
    import { filter, map, mergeMap } from 'rxjs/operators';
    
    @Injectable({
      providedIn: 'root'
    })
    export class CategoryService {
      constructor(private router: Router ) { }
      private routerEvents =  this.router.events;
      private navigationEndEvent = this.routerEvents
        .pipe(filter(event => event instanceof NavigationEnd))
      category$ = this.navigationEndEvent
        .pipe(
          mergeMap(() => this.rootRoute(this.router.routerState.root).data),
          map(({category}: any) => category)
        )
      private rootRoute = (route: ActivatedRoute): ActivatedRoute => {
        return route.firstChild ? this.rootRoute(route.firstChild) : route;
      }
    }
    

    组件

    constructor(private categoryService: CategoryService) {
      }
      category$ = this.categoryService.category$;
      ...
    }
    

    HTML

    <span>{{ category$ | async }}</span>
    

    Sample on Stackblitz

    【讨论】:

    • mergeMap(() =&gt; this.rootRoute(this.router.routerState.root).data) 是我的灵感来源,mergeMap(() =&gt; this.rootRoute(this.route).data)
    【解决方案2】:

    这就是我的应用程序组件中的内容

    constructor(private route: ActivatedRoute) {
    }
    
    ngOnInit(): void {
      this.router.events.pipe(
        filter(event => event instanceof NavigationEnd),
        map(() => this.rootRoute(this.route)),
        filter((route: ActivatedRoute) => route.outlet === 'primary'),
        mergeMap((route: ActivatedRoute) => route.data)
      ).subscribe((event: {[name: string]: any}) => {
        this.titleService.setRouteTitle(event['title']);
      });
    }
    
    private rootRoute(route: ActivatedRoute): ActivatedRoute {
      while (route.firstChild) {
        route = route.firstChild;
      }
      return route;
    }
    

    我的应用程序路由如下所示:

    { path: 'login', component: LoginComponent, data: { title: 'Login' } }
    

    而我的标题服务负责设置标题。

    我看到的和你的唯一区别是你在构造函数中绑定到路由器,而我在ngOnInit 中进行绑定。您可以尝试调用ngOnInit 中的内容吗?我不确定这是否会有所作为,但值得一试。

    【讨论】:

    • 我们注入的ActivatedRoute 确实有不同的名称。我还认为我们的两种方法都做同样的事情——它们只是在不同的地方被调用。如果您的 ngOnInit 仍然无法正常工作,那么我不知道发生了什么。下一步是在 stackblitz 中重新创建。
    • 我发布了赏金,我认为这个答案很棒,看看是否有更简单的代码,很多人有不同的答案,stackoverflow.com/questions/43512695/…this.title = route.root.firstChild.snapshot。数据['页面名称'];等
    【解决方案3】:

    在组件中获取路由数据的捷径。

    constructor(router:Router, route:ActivatedRoute) {
        router.events
          .filter(e => e instanceof NavigationEnd)
          .forEach(e => {
            this.title = route.root.firstChild.snapshot.data.category;
        });
    } 
    

    【讨论】:

      猜你喜欢
      • 2017-09-16
      • 2017-12-31
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      • 2020-11-04
      • 2016-04-14
      相关资源
      最近更新 更多