通过父组件请求一次数据并使所有子路由都可以访问? (角度2)

Request data once through parent component and make accessible to all child routes? (Angular2)

我有一个带有两个子路由的父组件。每个子路由都需要 use/access 从 GET 请求中检索到的相同数据。

我认为每次加载子路由时都查询服务器可能很浪费,所以我认为这样做的一个好方法是通过父路由查询一次服务器,然后通过共享数据双向服务,我正在尝试紧跟 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。但我不确定最好的方法是什么,所以非常感谢任何建议。

希望问题很清楚,如果您需要更多信息,请告诉我!谢谢

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