【问题标题】:Angular ActivatedRoute data returns an empty objectAngular ActivatedRoute 数据返回一个空对象
【发布时间】:2017-08-17 14:06:38
【问题描述】:

我有一条用一些数据注册的路线:

const routes: Routes = 
[
    {path: 'my-route', data: { title: 'MyTitle' }, component: MyComponent},
];

我正在尝试使用ActivatedRoute 访问路线数据:

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

@Component({...})
export class MyComponent implements OnInit {
  private routeData;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.routeData = this.route.data.subscribe((data) => {
      console.log(data); // this is returning an empty object {}
    });
  }
}

但由于某些原因,data 是一个空对象。

如何解决这个问题?

【问题讨论】:

标签: angular typescript angular-routing


【解决方案1】:

编辑:问题是我试图从<router-outlet> 外部的组件访问ActivatedRoute。所以看起来这是预期的行为。

但是我仍然认为我下面的回答对任何试图完成同样事情的人都有用。


我在 GitHub 上找到了一种解决方法(感谢 manklu),我使用它来完成我需要的工作:
import { Component, OnInit } from '@angular/core';
import { Router, RoutesRecognized } from '@angular/router';

@Component({...})
export class MyComponent implements OnInit {
  private routeData;

  constructor(private router: Router) { }

  ngOnInit() {
    this.router.events.subscribe((data) => {
      if (data instanceof RoutesRecognized) {
        this.routeData = data.state.root.firstChild.data;
      }
    });
  }
}

这样做this.routeData 将保存我需要的路线数据(在我的情况下是页面title)。

【讨论】:

  • 嘿,你的 github 链接在哪里?我只发现了这个错误报告:github.com/angular/angular/issues/19420 :)
  • 非常感谢!
  • 感谢您提供此解释。我只是通过 app.component.html 调用一个特定的组件——而不是<router-outlet></router-outlet>。干杯!
  • 如果您想获取 url 参数而不是您自己的数据,请使用:this.router.events.subscribe(val => { if (val instanceof RoutesRecognized) { var strId = val.state.root.firstChild.params["id"]; }});
  • 这解决了我的问题..我的意思是我忘了添加路由器插座...我快疯了。谢谢!
【解决方案2】:

获取Angular 8)之外的组件的路由自定义数据:

constructor(private router: Router) {}
    
ngOnInit() {
    this.router.events.subscribe(data => {
      if (data instanceof ActivationStart) {
        console.log(`Custom data`, data.snapshot.data);
      }
    });
  }

【讨论】:

  • 它在角度 10 中对我有用。我正在尝试在 appComponent 的主路由器出口中声明的子组件中的数据对象下捕获标题键。
  • 仅适用于导航,不适用于 Angular 12 上的页面加载
【解决方案3】:

我不知道所说的版本,但从 Angular 6 开始, 这对我有用:

(当然感谢 shinDath)

  routeData;
  ngOnInit() {
    //child route param doesnt go up to parent route params.
    this.router.events.subscribe((val) => {
      if (val instanceof ActivationEnd) {
        if(!$.isEmptyObject(val.snapshot.params)){
          this.routeData = val.snapshot.params;
        }
      }
    });
  }

【讨论】:

  • OP 试图获取的数据是路由配置中定义的数据。这不是我们要求的
【解决方案4】:

这是我的代码的一部分(注意:我使用的是 Angular 8):

constructor(private _router: Router, private _route: ActivatedRoute) {}

ngOnInit() {
  ...
  this.listenRouting();
}

listenRouting() {
    this._router.events.subscribe((router: any) => {
      routerUrl = router.url;
      if (routerUrl && typeof routerUrl === 'string') {
        routerList = routerUrl.slice(1).split('/');
        console.log("data.breadcrumbs", this._route.snapshot.routeConfig.children.find(child => child.path === routerList[routerList.length - 1]).data.breadcrumbs);
        ...
      }
    });
}

所以 data 是“隐藏”在 ActivatedRoute.snapshot.routeConfig.children 数组下。除其他外,每个子项都包含数据。 在我的例子中 data 是在 routing.module 中配置的,例如:

const routes: Routes = [
  { path: "facility-datas",
    component: FacilityTerminal,
    data: {
      breadcrumbs: "b ft"
    }
  },
...
];

【讨论】:

    【解决方案5】:

    这对我有用。在我这样做之前,也一直得到一个空对象。

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

    【讨论】:

      【解决方案6】:

      来自 Angular 贡献者的回答,link

      this.router.events.pipe(
          filter((e) => e instanceof NavigationEnd),
          map(() => {
              let route = this.activatedRoute;
      
              while (route.firstChild) {
                  route = route.firstChild;
              }
      
              return route;
          }),
          filter((route) => route.outlet === 'primary'),
          mergeMap((route) => route.data),
          tap(console.log)
      );
      
      
      constructor(
          private router: Router,
          private activatedRoute: ActivatedRoute,
      ) {}
      

      【讨论】:

        【解决方案7】:
        import { AfterViewInit, Component} from '@angular/core';
        import { ActivatedRoute } from '@angular/router';
        
        
        @Component({
          selector: 'app-users',
          templateUrl: './users.component.html',
          styleUrls: ['./users.component.scss']
        })
        export class UsersComponent implements AfterViewInit {
          paramId: string;
        
          constructor(private activatedRoute: ActivatedRoute) {}
        
          ngAfterViewInit(): void {
            this.paramId = this.activatedRoute.snapshot.params.id;
            console.log('paramId =', this.paramId);
          }
        
        }
        

        【讨论】:

        • 这会导致 ExpressionChangedAfterItHasBeenCheckedError 异常
        【解决方案8】:

        以下应该可以:

        constructor(private route: ActivatedRoute) {}
        
        ngOnInit() {
            console.log(this.route.snapshot.data);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-11
          • 2016-06-04
          • 1970-01-01
          • 2020-04-08
          • 1970-01-01
          • 2021-03-31
          • 2014-07-15
          相关资源
          最近更新 更多