如何获得角度2的当前路线自定义数据?

时间:2016-11-29 10:37:42

标签: angular angular2-routing

我已设置路线如下

const appRoutes: Routes = [
  {
    path: 'login',
    component: LoginComponent,
    data: {
      title: 'Login TTX'
    }
  },
  {
    path: 'list',
    component: ListingComponent,
    data: {
      title: ' TTX Home Page',
      module:'list'
    }
  },
  {
    path: '',
    redirectTo: '/login',
    pathMatch: 'full'
  },
];

现在,当我来'/list'路线然后'listing.component.ts'我写了下面的代码

export class ListingComponent {

  public constructor(private router:Router) {
      //here how i can get **data** of **list** routes

  }
}

12 个答案:

答案 0 :(得分:19)

适用于Angular 4 +

如果您将以下代码放在父级或上级组件(如AppComponent)中,那么它将无法正常工作。它仅适用于您已为其定义路径自定义数据的子级或低级组件:

 public constructor(private route:ActivatedRoute, private router:Router) {
      console.log(route.snapshot.data['title']);
  }

因此,如果您想从父级或更高级别组件全局访问路由自定义数据以访问路由自定义数据中的更改,那么您必须收听路由器事件,尤其是RoutesRecognized或{ {1}}事件。我将用NavigationEnd显示两个带有两个事件的程序:

第一种方法:

AppComponent

第二种方法正在使用:

   export class AppComponent implements OnInit, AfterViewInit {

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

    ngOnInit() {
         this.router
        .events
        .filter(event => event instanceof NavigationEnd)
        .map(() => {
          let child = this.activatedRoute.firstChild;
          while (child) {
            if (child.firstChild) {
              child = child.firstChild;
            } else if (child.snapshot.data && child.snapshot.data['custom_data']) {
              return child.snapshot.data['custom_data'];
            } else {
              return null;
            }
          }
          return null;
        }).subscribe( (customData: any) => {
          console.log(customData);
       });
    }
 }

注意:即使最后一个较短且通常有效,但是,如果您有嵌套路线,则鼓励使用第一个。

答案 1 :(得分:14)

  public constructor(private route:ActivatedRoute, private router:Router) {
      console.log(route.snapshot.data['title']);
  }

答案 2 :(得分:6)

它为无法导航的组件工作(如标题):

this.route.root.firstChild.snapshot.data['title']

和complate示例:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';


export class HeaderComponent implements OnInit {
  title: string;

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

  ngOnInit() {
    this.router.events.subscribe(event => {
      if(event instanceof NavigationEnd) {
        this.title = this.route.root.firstChild.snapshot.data['title']
      }
    });
  }    
}

cerdit to this answare

答案 3 :(得分:5)

在我测试了各种解决方案后,角度支持小组的答案实际上很好地解决了这个问题。

ActivatedRoute doesn't carry data,这是检测data: { page: 'login' }中页面变量的解决方案。

import { Router, RoutesRecognized } from '@angular/router';

export class AppComponent {
  page = '';
  constructor(private router: Router) {
    // listen to page variable from router events
    router.events.subscribe(event => {
      if (event instanceof RoutesRecognized) {
        let route = event.state.root.firstChild;
        this.page = 'page-' + route.data.page || '';
        console.log('Page', this.page);
      }
    });
  }
}

答案 4 :(得分:3)

asmmahmud的答案适用于Angular 5.x 但6.X打破this.router.events,因为rxjs 6.x有突破性变化。所以刚刚发现了一个更新:

import {filter} from 'rxjs/operators';
import {map, mergeMap} from 'rxjs/internal/operators';

router.events
          .pipe(filter(event => event instanceof NavigationEnd),
            map(() => {
              let route = activatedRoute.firstChild;
              let child = route;
              while (child) {
                if (child.firstChild) {
                  child = child.firstChild;
                  route = child;
                } else {
                  child = null;
                }
              }
              return route;
            }),
            mergeMap(route => route.data)
          )
          .subscribe(data => {
            console.log(data);
          });

答案 5 :(得分:2)

2021

Research Router events 深入了解复杂的路由信息​​。

但大多数时候不要想太多。

// 1. Subscribe in constructor to get events (OnInit and later are too late)
constructor(private router: Router) {
this.router.events.subscribe((event) => {
    // 2. Start with ActivationEnd, experiment with the other events
    if (event instanceof ActivationEnd) {
        // 3. if your data exists assign it for use!
        if (event.snapshot.data['searchSubject']) {
            this.searchSubject = event.snapshot.data['searchSubject'];
        }
    }
});

答案 6 :(得分:0)

这适用于app.component.ts(ng 5)

 constructor(
    private router: Router,
) {

 router.events.subscribe((routerEvent: Event) => {
       this.checkRouterEvent(routerEvent);
    });
}

checkRouterEvent(routerEvent: Event): void {
    if (routerEvent instanceof ActivationStart) {
        if (routerEvent.snapshot.data.custom_data) {
            this.currentpage = routerEvent.snapshot.data['custom_data'];
            console.log('4.' + this.currentpage);
        }

    }

答案 7 :(得分:0)

对于那些现在正在使用Angular 6+和最新的RXJS 6的用户,此处基于上面的回答:

路由示例:

const routes: Routes = [
  {path: 'home', component: HomeComponent, data: {title: 'Home'}},
  // {path: '', redirectTo: 'home', pathMatch: 'full'},
  {path: 'login', component: LoginComponent, data: {title: 'Login'}},
  {path: 'dashboard', component: DashboardComponent, data: {title: 'Dashboard'}, canActivate: [AppAuthGuard]},
  {path: 'eventDetails', component: EventCardComponent, data: {title: 'Details'}},
  {path: '**', redirectTo: 'home', pathMatch: 'full'},
];

如何获取标题示例:

ngOnInit() {
    this.routerEventSubscription = this.router.events
      .pipe(filter(event => event instanceof RoutesRecognized))
      .pipe(map((event: RoutesRecognized) => {
        return event.state.root.firstChild.data['title'];
      })).subscribe(title => {
        this.title = title;
      });
  }

答案 8 :(得分:0)

如果要获取当前的路线数据,可以从ActivatedRoute

获取
public constructor(private activatedRoute:ActivatedRoute) {
    console.log((activatedRoute.data as any).value);
}

答案 9 :(得分:0)

您可以订阅ActivatedRoute.data。这在某种程度上类似于@ dinesh-kumar的答案,但是我相信(activatedRoute.data as any).value确实是一个黑客,利用了activatedRoute.data被实现为BehaviorSubject的事实。但是ActivatedRoute.data被公开为Observable<Data>,因此正确的方法是订阅(不要忘记取消订阅或take(1)等)或使用async管道等

constructor(private route: ActivatedRoute) {
    this.route.data.subscribe((data) => {
      console.log(data);
    });
}

答案 10 :(得分:0)

尝试了很多之后,我找到了最佳解决方案

  private ngUnsubscribe$ = new Subject();

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

答案 11 :(得分:0)

this.router.events.subscribe((event: any) => {
        this.pageTitle = this.titleService.getTitle();
        // check instanceof  ChildActivationEnd  || ChildActivationStart
        if (event instanceof ChildActivationStart) {
            let pageIcon = event.snapshot?.firstChild?.children[0]?.data['icon'];
            this.pageIcon = pageIcon ? pageIcon : this.pageIcon;
        }
    })