0

我不确定这里的小细节,所以也许这甚至不应该工作 - 但似乎应该有一些解决方案。我有一个在选项卡中使用两个子组件的父组件,如下所示:

<div class="container" *ngIf="page === 'tab1'">
    <refresher-component></refresher-component>
    <child-component1></child-component1>
</div>
<div class="container" *ngIf="page === 'tab2'">
    <refresher-component></refresher-component>
    <child-component2></child-component2>
</div>

父级还有一个刷新组件,负责刷新两个选项卡中的数据。每个子组件都注入一个实现 Refreshable 接口的服务:

  • 子组件 1:constructor(private service1: Service1)
  • 子组件 2:constructor(private service2: Service2)

每个服务看起来像这样(将 1 替换为 2 用于第二个服务):

@Injectable()
export class Service1 implements Refreshable<Type1[]>

refersher-component看起来像这样:

public constructor(@Inject(RefresherServiceToken) public refreshableService: Refreshable<any>) {
    console.log('refreshable', this.refreshableService);
}

发生的情况是,当我加载页面时(默认为第一个选项卡),console.log输出 Service1. 但是,当切换到 Tab 2 时,再次调用了构造函数,但它也输出了 Service1。因此刷新也是对Service1的数据进行的,不影响Service2。

这是正常行为吗,因为路线没有改变,我需要添加一些东西来重置服务吗?一般来说,有没有一种简单的方法来解决这种行为?(角度 8)

4

1 回答 1

0

看起来我的故障排除中缺少的是 RefresherServiceToken 的提供者。这一定存在于某个地方。在我的情况下,提供的是在作为父组件的父级的“空”模块中给出的,并且由于在refresher-component子级之外,它也不能在child-component级别上被覆盖。

我可以想到三个解决方案:

最简单的:

移动refresher-component里面的每一个child-component。在我的实际代码中它有点困难,但在上面的例子中它是微不足道的。之后,在子组件级别添加必要的提供者,例如:

providers: [
    {provide: RefresherServiceToken, useExisting: Service2}
]

在这种情况下,即使父级别上有提供程序,它也会被覆盖。

易于实现,以后难以阅读/遵循

parent-component级别动态配置提供程序。有几种方法可以做到这一点,如下所述: How to add providers to Injector dynamic?

可能最难实现,但最容易掌握

更改这些页面的构建方式,因为两个子组件应该位于两个完全独立的页面/路由中,而共享模板部分(例如,页眉/页脚)位于共享组件中。这完全解决了这个问题,因为两个子组件都没有一个父组件,因此它们不能具有相同的提供者。如第一个示例中所述,需要为它们中的每一个定义自然独立的提供程序。

于 2020-02-19T16:49:17.487 回答