Angular 6 - 无法检索静态数据

时间:2018-06-18 15:24:50

标签: angular typescript angular-routing

问题:永远不会通过订阅ActivatedRoute中的数据对象来检索路由中定义的静态数据。其他一切似乎工作正常,数据对象不是null,但我无法从中获取数据。当我尝试从数据对象调试数据时它输出“未定义”,当我尝试将其绑定到UI时没有显示,但是当我在Chrome中查看ActivatedRoute消息时它有数据。经过多次尝试后,我很确定我的语法应该基于很多例子,因此Angular 6中的某些内容可能会发生变化,或者Angular有什么问题?

路线代码:

    const appRoutes: Routes = [
  {
    path: "article",
    redirectTo: "/article/partners",
    pathMatch: "full"
  },
  { 
    path: "article",
    children: [
      {
        path: "bawo",
        component: BawoArticleComponent,
        data: { title: 'BaWo' }
      },
      {
        path: "goldenhands",
        component: GoldenHandsArticleComponent,
        data: { title: 'Golden Hands' }
      },
      {
        path: "investors",
        component: InvestorsArticleComponent,
        data: { title: 'Investors' }
      },
      {
        path: "partners",
        component: PartnersArticleComponent,
        data: { title: 'Partners' }
      }
    ]
  },
  {
    path: "**",
    redirectTo: "/article/partners"
  }
];

检索组件代码(我已经评论了相关代码的位置):

export class ArticleSelectorComponent implements OnInit {
  arrowFader: string;

  opacity: string;

  fadeTimer: Observable<number>;

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

  ngOnInit() {
    this.router.events.subscribe((e: RouterEvent) => {
      this.fadeTimer = timer(0, 150);
      let subscription = this.fadeTimer.subscribe(currentValue => {

        let calc = currentValue & 3;

        if (calc == 0) {
          this.arrowFader = '>';
          this.opacity = '0.5';
        }
        else if (calc == 1) {
          this.arrowFader = '>>';
          this.opacity = '0.65';
        }
        else {
          this.arrowFader = '>>>';
          this.opacity = '0.8';
        }
      });

      this.fadeTimer.subscribe(currentValue => {
        if(currentValue >= 14) {
          subscription.unsubscribe();
          this.opacity = '1.0';
        }
      });
    });

// THIS DOESN'T WORK!!!!
    this.activatedRoute.data.subscribe((data: Data) => {
      console.log(data['title']);
    });
  }

// not relevant, this code is ran with parameter at html buttons
  navToArticle(num: number) {
    let navStr = '';
    switch(num){
      case 1: {
        navStr = '/article/bawo';
        break;
      }
      case 2: {
        navStr = '/article/goldenhands';
        break;
      }
      case 3: {
        navStr = '/article/partners';
        break;
      }
      case 4: {
        navStr = '/article/investors';
        break;
      }
    }

    this.router.navigateByUrl(navStr);
  }
}

AppComponent的HTML代码(带有组件指令):

<div class="site">

    <div class="top">
        <div class="anim-in-left">
            <app-domains></app-domains>
        </div>

        <div class="anim-in-down top-title">
            <h1 class="top-title-text">{{ topTitle }}</h1>
        </div>

        <div class="anim-in-right">
            <app-presence></app-presence>
        </div>
    </div>

    <div class="anim-in-up middle">
        <app-article-selector></app-article-selector>
    </div>
</div>

4 个答案:

答案 0 :(得分:4)

尝试以下片段,因为如果您立即订阅activatedRoute,它只订阅当前组件在路由器配置中注册的路由器数据更改,我只是添加了NavigationEnd过滤器,因此不会触发所有其他不需要的事件对于这个要求。

...    
ngOnInit() {
  ...
  this.title$ = this.router.events.pipe(
    filter((event) => event instanceof NavigationEnd),
    map(_ => this.activatedRoute),
    map((route) => {
      while (route.firstChild) {
        route = route.firstChild;
      }

      return route;
    }),
    mergeMap((route) => route.data),
    map((data) => data.title)
  );
  this.title$.subscribe(title => console.log(title));
  ...
}
...

答案 1 :(得分:1)

我分叉了Angular示例并在 - &gt;处复制了代码(在某种程度上)

我发现的唯一区别是如何激活组件。

  1. 当刚刚导入为对象时,ArticleSelectorComponent永远不会成为路由生命周期的一部分。
  2. 当它成为路由生命周期的一部分(作为路由组件)时,它就像一个魅力:D
  3. 我没有尝试@ abinesh-devadas响应,但如果你真的想要获得data元素而不管组件生命周期如何,这看起来是更好的解决方案。

答案 2 :(得分:1)

幸运的是,这个问题已经回答了:

querySelector

https://stackoverflow.com/a/46305085/1510754

基于此,我们提供了更完整的答案:

import { Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { Router, RoutesRecognized } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})

export class AppComponent implements OnInit {

  private baseTitle = 'MySite';

  get title(): string {
    return this.titleService.getTitle();
  }

  constructor(
    private router: Router,
    private titleService: Title,
  ) {
  }

  ngOnInit() {
    this.router.events.subscribe(event => {
      if (event instanceof RoutesRecognized) {
        const route = event.state.root.firstChild;
        let title = this.baseTitle;
        if (route.data['title']) {
          title = route.data['title'] + ' - ' + title;
        }
        this.titleService.setTitle(title);
      }
    });
  }

}

注意:设置title不需要<title>吸气剂,因为使用titleService即可完成。但是您可以使用吸气剂来更新<h1>

答案 3 :(得分:0)

下面的代码直到最近都工作良好:

this.router.events
    .pipe(
        filter((event: any) => 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((event) => {
            this.titleService.setTitle(event['title']);
            console.log(event);
        }

我认为自从升级到Angular 6.0以来。无论我尝试什么,我都会得到undefined