我不确定这里的小细节,所以也许这甚至不应该起作用——但似乎应该有一些解决方案。我有一个在选项卡中使用两个子组件的父组件,如下所示:
<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>
父级还有一个刷新组件,负责刷新两个选项卡中的数据。每个子组件都注入一个实现可刷新接口的服务:
- 子组件 1:
constructor(private service1: Service1)
- 子组件 2:
constructor(private service2: Service2)
每个服务如下所示(将 1 替换为 2 表示第 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。但是,当更改为选项卡 2 时,将再次调用构造函数,但它也会输出 Service1。因此,刷新也是在服务1的数据上完成的,不会影响服务2。
这是正常行为吗,因为路由不会更改,我是否需要添加一些内容来重置服务?有没有一种简单的方法来解决此行为?(角度 8(
看起来我的故障排除中缺少的是RefresherServiceToken的提供者。这必须存在于某个地方。在我的例子中,提供的是在父组件的父组件的"空"模块中给出的,并且由于refresher-component
在子组件之外,因此也不能在child-component
级别覆盖它。
我能想到三种解决方案:
简单:
在每个child-component
内移动refresher-component
。在我的实际代码中,这有点困难,但在上面的例子中,这是微不足道的。之后,在子组件级别添加必要的提供程序,例如:
providers: [
{provide: RefresherServiceToken, useExisting: Service2}
]
在这种情况下,即使父级别有提供程序,也会重写它。
易于实现,以后难以阅读/遵循
在parent-component
级别动态配置提供程序。有几种方法可以做到这一点,如下所述: 如何动态地将提供程序添加到注入器?
可能是最难实现的,但最容易掌握
更改这些页面的构建方式,因为两个子组件应位于两个完全独立的页面/路由中,而共享模板部件(例如页眉/页脚(位于共享组件中。这完全可以解决此问题,因为两个子组件没有一个父组件,因此它们不能具有相同的提供程序。当然,需要为每个提供程序定义单独的提供程序,如第一个示例中所述。