通过父组件请求数据一次,并使所有子路径都可访问? (Angular2)

时间:2017-07-18 12:01:15

标签: angular angular2-routing angular2-services

我有一个包含两个子路由的父组件。每个子路由都需要使用/访问从GET请求中检索的相同数据。

我认为每次加载子路由时查询服务器可能会很浪费,所以我认为这样做的好方法是通过父路由查询服务器一次,然后通过bi共享数据 - 我试图在angular docs之后密切实施的方向服务。

但是,这两个子组件都不能订阅服务中设置的观察者,我不确定为什么?

以下是一些代码段;

父组件:

@Component({
  selector: 'parent',
  template: `
 <div>

      <ul>
        <li><a routerLinkActive="active" routerLink="child1">Child1</a></li>
        <li><a routerLinkActive="active" routerLink="child2">Child2</a></li>
      </ul>

    </div>

    <router-outlet></router-outlet>
  `,
})
export class ParentComponent implements OnInit {


  constructor(private testService: TestService) {}


  ngOnInit(){
        this.testService.getData(this.testService.createProfileData())
  }

}

子组件(它们目前具有相同的代码)

export class Child1Component implements OnInit {


  public profileData: any;

  constructor(private testService: TestService) {}

  ngOnInit(){
    this.testService.profile$.subscribe((data) => {
        console.log(data)
        this.profileData = data;
      })
  }
}

测试服务:

import { Injectable } from '@angular/core';

import 'rxjs/Rx';
import {Observable} from 'rxjs';
import { Subject }    from 'rxjs/Subject';

@Injectable()
export class TestService {

  profile = new Subject<any>();

  profile$ = this.profile.asObservable();

  getData(obj:any) {
    console.log(obj)
    return this.profile.next(obj);
  }

  createProfileData(){
    return {name:'test-me!'}
  }

}

这是一个包含所有代码的人:

https://plnkr.co/edit/CCnZbHTzU8R0uKo0WtbD?p=preview

这里所需的输出是父组件向服务器发送GET请求(通过在此处创建一个简单对象来演示),然后更新服务中的profile = new Subject<any>();

然后,每次调用子路由时,他们都会通过服务订阅此观察者,并且无需每次都查询服务器即可访问数据。

我不确定这是否是实现这种结果的正确方法?如果是的话,我不确定为什么它在我的例子中不起作用?

我开始研究其他可能有用的方法,例如ngrx/store。但是我不确定最好的方法是什么,所以任何建议都非常感激。

希望问题很清楚,如果您需要更多信息,请与我们联系!感谢

1 个答案:

答案 0 :(得分:1)

Angular resolver来救援!

首先,定义路由配置如下:

{
    path: 'parent',
    component: ParentComponent,
    resolve: {
      data: DataResolverService
    },
    children: [
      {
        path: 'child1',
        component: Child1Component,
      },
      {
        path: 'child2',
        component: Child2Component,
      }
    ]
  },

其中 DataResolverService

@Injectable()
export class DataResolverService implements Resolve<any> {

    constructor(private testService: TestService) {
    }

    resolve(route: ActivatedRouteSnapshot): Observable<any> {
        return this.testService.getData().first();
    }

}

然后在你的组件中:

constructor(private activatedRoute: ActivatedRoute) {
    }

    ngOnInit() {
        this.activatedRoute.parent.data.pluck('data').subscribe((data: any) => {
            this.data = data;        
        });
    }