Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用ActivatedRoute检索Angular2路由上的数据属性,而不考虑路由嵌套的级别_Angular_Typescript_Angular2 Routing - Fatal编程技术网

使用ActivatedRoute检索Angular2路由上的数据属性,而不考虑路由嵌套的级别

使用ActivatedRoute检索Angular2路由上的数据属性,而不考虑路由嵌套的级别,angular,typescript,angular2-routing,Angular,Typescript,Angular2 Routing,我已经定义了一些路线,如下所示: export const AppRoutes: Routes = [ {path: '', component: HomeComponent, data: {titleKey: 'homeTitle'}}, {path: 'signup', component: SignupComponent, data: {titleKey: 'SIGNUP_FORM.TITLE'}}, {path: 'signin', component: SigninComp

我已经定义了一些路线,如下所示:

export const AppRoutes: Routes = [
  {path: '', component: HomeComponent, data: {titleKey: 'homeTitle'}},
  {path: 'signup', component: SignupComponent, data: {titleKey: 'SIGNUP_FORM.TITLE'}},
  {path: 'signin', component: SigninComponent, data: {titleKey: 'SIGNIN_FORM.TITLE'}},
  {path: 'sendpasswordresetinformation', component: SendPasswordResetInformationComponent},
  {path: 'password/reset/:userAccountToken', component: PasswordResetComponent},
  {
    path: 'dashboard', component: DashboardComponent, children: [
    {path: '', component: DashboardSummaryComponent},
    {
      path: 'message', children: [
      {path: '', component: MessageSummaryComponent, data: {titleKey: 'MESSAGE_LIST.TITLE'}},
      {path: 'conversation/:otherId', component: MessageConversationComponent, data: {titleKey: 'XXX'}}]
    },
    {
      path: 'useraccount', component: UserAccountComponent, children: [
      {
        path: '',
        component: UserAccountSummaryComponent,
        data: {titleKey: 'XXX'},
        resolve: {
          userAccount: UserAccountResolve
        }
      },
      {path: 'address', component: UserAccountAddressComponent, data: {titleKey: 'ADDRESS_FORM.TITLE'}},
      {path: 'email', component: UserAccountEmailComponent, data: {titleKey: 'EMAIL_FORM.TITLE'}},
      {
        path: 'emailnotification',
        component: UserAccountEmailNotificationComponent,
        data: {titleKey: 'EMAIL_NOTIFICATION_FORM.TITLE'}
      },
      {path: 'firstname', component: UserAccountFirstNameComponent, data: {titleKey: 'FIRST_NAME_FORM.TITLE'}},
      {path: 'password', component: UserAccountPasswordComponent, data: {titleKey: 'PASSWORD_FORM.TITLE'}}]
    }]
  }];
@Component({
  selector: 'app',
  template: `
              <section class="container-fluid row Conteneur">
                 <appNavbar></appNavbar>
                 <section class="container">
                    <router-outlet (activate)="setTitle($event)"></router-outlet>
                 </section>
              </section>
              <section class="container-fluid">  
                <appFooter></appFooter>
              </section>
              `,
  directives: [NavbarComponent, FooterComponent, SigninComponent, HomeComponent, ROUTER_DIRECTIVES]
})
export class AppComponent implements OnInit {

  constructor(private translate: TranslateService,
              private sessionService: SessionService,
              private titleService: Title,
              private activatedRoute: ActivatedRoute) {
    let userLang = 'fr';
    translate.use(userLang);
    moment.locale(userLang);
  }

  ngOnInit() {
    this.sessionService.reloadPersonalInfo();
  }

  setTitle($event) {
    this.activatedRoute.data.map(data=>data['titleKey'])
      .do(key=>console.log(key))
      .switchMap(key=>this.translate.get(key))
      .subscribe(translation=>this.titleService.setTitle(translation));
  }
}
有些路线是其他路线的后代

我想找到一种方法来检索
数据
上的
标题键
属性,而不管该路由是顶级路由还是另一路由的子路由

以下是我尝试过的:

export class AppComponent implements OnInit {

  constructor(private translate: TranslateService,
              private sessionService: SessionService,
              private titleService: Title,
              private activatedRoute: ActivatedRoute) {
    let userLang = 'fr';
    translate.use(userLang);
    moment.locale(userLang);
  }

  ngOnInit() {
    this.sessionService.reloadPersonalInfo();
  }

  setTitle($event) { 
    this.translate.get(this.activatedRoute.snapshot.data['titleKey'])
     .subscribe(translation=>this.titleService.setTitle(translation));
  }
}
this.activatedRoute.snapshot.data['titleKey']
未定义的

是否有人可以建议如何检索route
data
上的属性,而不考虑路由的嵌套级别

编辑:在阅读官方文件后,我尝试在
ActivatedRoute
实例的数据属性上使用
map
操作符,如下所示:

export const AppRoutes: Routes = [
  {path: '', component: HomeComponent, data: {titleKey: 'homeTitle'}},
  {path: 'signup', component: SignupComponent, data: {titleKey: 'SIGNUP_FORM.TITLE'}},
  {path: 'signin', component: SigninComponent, data: {titleKey: 'SIGNIN_FORM.TITLE'}},
  {path: 'sendpasswordresetinformation', component: SendPasswordResetInformationComponent},
  {path: 'password/reset/:userAccountToken', component: PasswordResetComponent},
  {
    path: 'dashboard', component: DashboardComponent, children: [
    {path: '', component: DashboardSummaryComponent},
    {
      path: 'message', children: [
      {path: '', component: MessageSummaryComponent, data: {titleKey: 'MESSAGE_LIST.TITLE'}},
      {path: 'conversation/:otherId', component: MessageConversationComponent, data: {titleKey: 'XXX'}}]
    },
    {
      path: 'useraccount', component: UserAccountComponent, children: [
      {
        path: '',
        component: UserAccountSummaryComponent,
        data: {titleKey: 'XXX'},
        resolve: {
          userAccount: UserAccountResolve
        }
      },
      {path: 'address', component: UserAccountAddressComponent, data: {titleKey: 'ADDRESS_FORM.TITLE'}},
      {path: 'email', component: UserAccountEmailComponent, data: {titleKey: 'EMAIL_FORM.TITLE'}},
      {
        path: 'emailnotification',
        component: UserAccountEmailNotificationComponent,
        data: {titleKey: 'EMAIL_NOTIFICATION_FORM.TITLE'}
      },
      {path: 'firstname', component: UserAccountFirstNameComponent, data: {titleKey: 'FIRST_NAME_FORM.TITLE'}},
      {path: 'password', component: UserAccountPasswordComponent, data: {titleKey: 'PASSWORD_FORM.TITLE'}}]
    }]
  }];
@Component({
  selector: 'app',
  template: `
              <section class="container-fluid row Conteneur">
                 <appNavbar></appNavbar>
                 <section class="container">
                    <router-outlet (activate)="setTitle($event)"></router-outlet>
                 </section>
              </section>
              <section class="container-fluid">  
                <appFooter></appFooter>
              </section>
              `,
  directives: [NavbarComponent, FooterComponent, SigninComponent, HomeComponent, ROUTER_DIRECTIVES]
})
export class AppComponent implements OnInit {

  constructor(private translate: TranslateService,
              private sessionService: SessionService,
              private titleService: Title,
              private activatedRoute: ActivatedRoute) {
    let userLang = 'fr';
    translate.use(userLang);
    moment.locale(userLang);
  }

  ngOnInit() {
    this.sessionService.reloadPersonalInfo();
  }

  setTitle($event) {
    this.activatedRoute.data.map(data=>data['titleKey'])
      .do(key=>console.log(key))
      .switchMap(key=>this.translate.get(key))
      .subscribe(translation=>this.titleService.setTitle(translation));
  }
}
@组件({
选择器:“应用程序”,
模板:`
`,
指令:[NavbarComponent、FooterComponent、SigninComponent、HomeComponent、ROUTER_指令]
})
导出类AppComponent实现OnInit{
构造函数(私有翻译:翻译服务,
专用会话服务:会话服务,
私人产权服务:产权,
专用activatedRoute:activatedRoute){
让userLang='fr';
使用(userLang);
moment.locale(userLang);
}
恩戈尼尼特(){
this.sessionService.reloadPersonalInfo();
}
setTitle($event){
this.activatedRoute.data.map(data=>data['titleKey'])
.do(key=>console.log(key))
.switchMap(key=>this.translate.get(key))
.subscribe(translation=>this.titleService.setTitle(translation));
}
}

然而,
始终是未定义的…

更新

您可以在下面的
AppComponent
中尝试

   constructor(private translate: TranslateService,
          private sessionService: SessionService,
          private titleService: Title,
          private activatedRoute: ActivatedRoute) {

      this.router.events.subscribe((arg) => {
         if(arg instanceof NavigationEnd) { 
           console.log(this.getTitle(this.activatedRoute.snapshot));
         }
      });
   }

   getTitle = (snapshot) => {
     if(!!snapshot && !!snapshot.children && !!snapshot.children.length > 0){
      return this.getTitle(snapshot.children[0]);
     }
    else if(!!snapshot.data && !!snapshot.data['titleKey']){
      return snapshot.data['titleKey'];
    }
    else{
      return '';
    }
   }
看起来有点老套,但很管用

旧的

你可以在下面试试

{
  path: 'conversation/:otherId', 
  component: MessageConversationComponent, 
  data: {titleKey: 'XXX'},
  // add below resolve
  resolve: {
            titleKey: MessageConversationResolve
  }      
}
添加一个新服务MessageConversationResolve.ts,并将其适当地添加到提供者中

import { Injectable } from '@angular/core';
import { Router, Resolve,ActivatedRouteSnapshot } from '@angular/router';
import { Observable }             from 'rxjs/Observable';

@Injectable()
export class AdminDetailResolve implements Resolve<any> {
  constructor(private router: Router,
              private titleService: Title) {}

  resolve(route: ActivatedRouteSnapshot): Observable<any> | Promise<any> | any {
    // route.data will give you the titleKey property
    // console.log(route.data);
    // you may consume titleService here to setTitle

    return route.data.titleKey;
 }
}
从'@angular/core'导入{Injectable};
从'@angular/Router'导入{Router,Resolve,ActivatedRouteSnapshot};
从“rxjs/Observable”导入{Observable};
@可注射()
导出类AdminDetailResolve实现解析{
构造函数(专用路由器:路由器、,
私人所有权服务:所有权){}
解析(路由:ActivatedRouteSnapshot):可观察的|承诺|任何{
//route.data将为您提供titleKey属性
//控制台日志(路由数据);
//您可以在此处使用titleService设置标题
返回路径.data.titleKey;
}
}
下面是支持上述解决方案的角度版本

Angular 2版本:2.0.0-rc.5


角度路由器版本:3.0.0-rc.1

我们也遇到了同样的问题。我们决定换一种方式去做。我们订阅路由器本身上可观察到的
事件,而不是尝试侦听ActivatedRoute上发出的数据:

import { Component } from "@angular/core";
import { NavigationEnd, Router } from "@angular/router";

declare var module: any;

@Component({
    moduleId: module.id,
    selector: "app-layout",
    templateUrl: "main-layout.component.html"
})
export class LayoutComponent {
    titleKey: string;

    constructor(private router: Router){}

    ngOnInit() {
        this.router.events
            .filter((event: any) => event instanceof NavigationEnd)
            .subscribe(() => {
                var root = this.router.routerState.snapshot.root;
                while (root) {
                    if (root.children && root.children.length) {
                        root = root.children[0];
                    } else if (root.data && root.data["titleKey"]) {
                        this.titleKey = root.data["titleKey"];
                        return;
                    } else {
                        return;
                    }
                }
            });
    }
}
请注意,我们使用的是顶级组件中的值,但需要来自最深子路由的数据。您应该能够非常轻松地将其转换为每当
titleKey
更改值时都会发出事件的服务


希望这能有所帮助。

我偶然发现了一个很好的教程,其中有一个干净的解决方案:

以下是我最后使用上述教程中的解决方案,并使用,将路线数据中指定的
标题键
转换为正确的标签得出的结论:

@组件({
选择器:“应用程序”,
封装:视图封装。无,
styleUrls:['../styles/bootstrap.scss'],
模板:`
`
})
导出类AppComponent实现OnInit{
构造函数(私有翻译:翻译服务,
专用sessionSigninService:sessionSigninService,
私人产权服务:产权,
专用路由器:路由器,
专用activatedRoute:activatedRoute){
让userLang='fr';
使用(userLang);
moment.locale(userLang);
}
恩戈尼尼特(){
这是路由器事件
.filter(事件=>NavigationEnd的事件实例)
.map(()=>this.activatedRoute)
.map(路线=>{
而(route.firstChild)route=route.firstChild;
返回路线;
})
.filter(route=>route.outlet=='primary')
.mergeMap(route=>route.data)
.mergeMap(数据=>this.translate.get(数据['titleKey']))
.subscribe(translation=>this.titleService.setTitle(translation));
}
}

你好。谢谢你的回复。嗯。这不是
解析的本意。我只是在处理简单的钥匙。在这里使用
resolves
不是太过分了吗?最简单的解决方案是从子组件本身中获取数据,但我猜您不想在子组件中插入标题服务,如果不是这样,您可以使用
this.route.data.subscribe(data=>{console.log(data);})
在子组件内部,轻松获取数据。希望这有帮助!!我希望尽量减少重复,我不希望侦听器在我的所有组件上重复,即
setTitle
。我想它应该只在一个地方。setTitle是如何触发的?当你改变路线的时候?或者点击按钮?当路线被
(activate)
事件激活时。这既可以实现非常强大的功能,也可以实现非常荒谬的代码量。我在pipe()流中接受答案的“While”方法时遇到了问题(它使我的应用程序崩溃),所以你的解决方案也在这里实现了!谢谢