通过服务将 parent 路由参数传递给 child

Passing parent route params to child via service

我正在尝试使用 Angular 团队目前推荐的方法将路由参数从 parent 组件传递到 child 组件:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

parent 能够成功订阅正确发出的服务。然而,child 在页面加载时没有收到任何东西。

服务

@Injectable()
export class AbcService {
  public paramSource: Subject<any> = new Subject<any>();
  public getParams(params) {
    this.paramSource.next(params);
  }
}

Parent

import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AbcService } from './abc.service';

@Component({
  providers: [AbcService],
  ...,
})

export class AbcComponent {
  constructor(
    private route: ActivatedRoute,
    private abcService: AbcService,
  ) {
    route.params.subscribe(
      (params) => abcService.getParams(params);
    );
  }
}

Child

export class AbcChildComponent {
  constructor(private abcService: AbcService) {
      abcService.paramSource.subscribe((params) => {
          console.log(params);
      });
  }
}

因为 AbcService 的实例在 parent 和 child 组件中 不同

请在parent module

中声明您的AbcService
@NgModule({
  imports: [
    ...
  ],
  declarations: [
    ChildComponent,
    ParentComponent
  ],
  providers: [
    AbcService
  ]
})
export default class ParentModule { }

您不再需要在 parent 组件中声明。

Parent

@Component({
  providers: [AbcService], // <-- Remove this
  ...,
})

还有一点,我认为我们应该把订阅放在ngOnInit()而不是构造函数中。

The constructor is for simple initializations like wiring constructor parameters to properties. It's not for heavy lifting. We should be able to create a component in a test and not worry that it might do real work — like calling a server! — before we tell it to do so.

https://angular.io/docs/ts/latest/tutorial/toh-pt4.html#!#the-ngoninit-lifecycle-hook


我的源结构

|- parent.module.ts
|- parent.component.ts
|- parent.routing.ts
|- shared.service.ts
\--- child
       |- child.component.ts

parent.html

<p>Some shared information</p>
<!-- Use router to load child component -->
<router-outlet></router-outlet>

Why example work?

我猜是因为没有使用路由器来初始化 child 组件。

在我的例子中,child 组件仅在路由到时初始化。

P/s:如有不妥之处,欢迎指正。

我认为代码是正确的,但是事件丢失了。在您下次呼叫时,没有人在听主题。一种方法是使用 ReplaySubject 另一种方法是在 ngAfterViewInit 回调中调用 next。