【问题标题】:Avoid Multiple Instances of Service in Angular避免 Angular 中的多个服务实例
【发布时间】:2020-10-23 14:47:06
【问题描述】:

我在网上做了一些研究,我发现我面临的问题是正在创建多个服务实例,我想避免这种情况。有人可以看看我的代码并找出我需要做的改变吗?

使用被复制的主要服务的第二个服务。

export class SecondaryService {
    constructor(private primarySvc: IPrimaryService){
        this.primarySvc.someSubject.subscribe(() => {});
    }
}

主服务(被复制的那个)

export class PrimaryService {
    someSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
    constructor(){}
}

主要服务提供商

@Injectable()
export class PrimaryServiceProvider extends PrimaryService {
     constructor(){
          super();
     }
}

二级服务商

@Injectable()
export class SecondaryServiceProvider extends SecondaryService {
    constructor(private PrimaryProvider: PrimaryServiceProvider){
        super(PrimaryProvider);
    }
}

app.module.ts

 @NgModule({
     declaration: [SecondaryComponent],
     exports: [SecondaryComponent],
     imports: [BrowserModule],
     providers: [SecondaryServiceProvider, PrimaryServiceProvider ]
 })
 export class SearchModule{}

现在我正在尝试使用我在本地环境中制作的组件,看起来像这样:

app.module.ts

 @NgModule({
     declaration: [AppComponent, HomeComponent],
     imports: [SearchModule, BrowserModule],
     providers: [PrimaryServiceProvider, SecondaryServiceProvider],
     bootstrap: [AppComponent]
 })
 export class AppModule{}

home.component.ts

export class HomeComponent {
    constructor( primarySvc: PrimaryServiceProvider, 
        secondarySvc: SecondaryServiceProvider) {
        this.primarySvc.someSubject.next(false);
    }
}

现在我确定主服务有两个实例,因为 someSubject 不同步,并且 SecondarySvc 中的订阅没有从 home.component.ts 获取任何值

请告诉我需要在哪里进行更改

谢谢!!

【问题讨论】:

  • 你能在stackblitz.com上运行应用吗
  • 从 SearchModule 中删除提供者
  • @DiakoAmir 不幸的是我不知道如何在 stackblitz.com 中创建本地环境,我觉得没有它我将无法重新创建问题

标签: javascript angular typescript angular6 singleton


【解决方案1】:

回答我自己的问题:

由于导入时文件路径不正确,服务被重复。 Windows 允许您使用不区分大小写的文件路径,这可能会在每次使用模块时创建多个实例。

【讨论】:

  • 对我来说,这是我使用 Lerna 在 Webstorm 上的自动导入。它导致在不应该创建的时候创建相对路径。
【解决方案2】:

我认为您使用 PrimaryServiceProviderSecondaryServiceProvider 服务进行了过度设计。

要创建单例服务,只需在 Injectable 装饰器中设置 providedIn: 'root' 选项,如下所示:

@Injectable({ providedIn: 'root' })
export class SecondaryService {}

最后,确保不要在任何providers 数组中注册单例服务。

查看有关此here 的官方文档。

【讨论】:

  • 感谢@yasser 的回复,这是一个巨大项目的一部分,所以我无法删除这两个服务中的任何一个。其次,复制的是 PrimaryService 而不是 SecondaryService跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2014-08-11
  • 2020-10-11
  • 1970-01-01
相关资源
最近更新 更多