当前位置: 首页 > 知识库问答 >
问题:

如何在Angular 2中创建单例服务?

何禄
2023-03-14

我读过,无融资创业时注入应该让所有孩子共享同一个实例,但是我的主组件和头组件(主应用程序包括头组件和路由器出口)各自获得了我的服务的单独实例。

我有一个FacebookService,用来调用facebook javascript api,还有一个UserService,使用FacebookService。这是我的引导程序:

bootstrap(MainAppComponent, [ROUTER_PROVIDERS, UserService, FacebookService]);

从我的日志记录来看,引导调用似乎完成了,然后我看到在每个构造函数、MainAppComponent、HeaderComponent和DefaultComponent中的代码运行之前创建了FacebookService,然后是UserService:

共有3个答案

梁新觉
2023-03-14

我知道angular像Thierry说的那样有层次结构。

但是我在这里有另一个选择,以防你找到一个你真的不想在父节点注入它的用例。

我们可以通过创建服务实例来实现这一点,并在提供时始终返回该实例。

import { provide, Injectable } from '@angular/core';
import { Http } from '@angular/core'; //Dummy example of dependencies

@Injectable()
export class YourService {
  private static instance: YourService = null;

  // Return the instance of the service
  public static getInstance(http: Http): YourService {
    if (YourService.instance === null) {
       YourService.instance = new YourService(http);
    }
    return YourService.instance;
  }

  constructor(private http: Http) {}
}

export const YOUR_SERVICE_PROVIDER = [
  provide(YourService, {
    deps: [Http],
    useFactory: (http: Http): YourService => {
      return YourService.getInstance(http);
    }
  })
];

然后在组件上使用自定义的提供方法。

@Component({
  providers: [YOUR_SERVICE_PROVIDER]
})

您应该有一个单例服务,而不依赖于分层注入器。

我并不是说这是一种更好的方法,只是为了防止有人遇到无法实现分层喷射器的问题。

宰烈
2023-03-14

杰森完全正确!它是由依赖注入的工作方式引起的。它基于分层注射器。

Angular2应用中有多个喷油器:

  • 在应用程序无融资创业时配置的根用户
  • 每个组件一个注射器。如果您在另一个组件中使用组件。组件注入器是父组件1的子组件。应用程序组件(您在引导应用程序时指定的组件)将根注入器作为父组件)。

当Angular2试图在组件构造函数中注入一些东西时:

  • 它查看与组件关联的注射器。如果有匹配的,它将使用它来获取相应的实例。此实例是懒惰创建的,是此注入器的单例。
  • 如果这个级别没有提供程序,它将查看父注入器(以此类推)。

因此,如果您想为整个应用程序提供一个单例,您需要在根注入器或应用程序组件注入器级别定义提供程序。

但Angular2将从底部查看喷油器树。这意味着将使用最低级别的提供程序,并且关联实例的范围将是此级别。

有关更多详细信息,请参见此问题:

  • 在angular 2(Beta版)中,将一个服务注入另一个服务的最佳方式是什么
瞿兴朝
2023-03-14

创建单例服务的推荐方式已更改。现在建议在服务的@Injectable装饰器中指定它应该在“root”中提供。这对我来说很有意义,不再需要列出模块中提供的所有服务。您只需在需要时导入服务,它们就会在适当的位置进行注册。您还可以指定模块,以便仅在导入模块时提供该模块。

@Injectable({
  providedIn: 'root',
})
export class ApiService {
}
  • https://angular.io/guide/singleton-services

对于NgMoules,我认为现在的方法是创建一个包含您的服务类的“核心模块”,并在模块的提供者中列出服务。然后,在主应用程序模块中导入核心模块,该模块将为构造函数中请求该类的任何子类提供一个实例:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ApiService } from './api.service';

@NgModule({
    imports: [
        CommonModule
    ],
    exports: [ // components that we want to make available
    ],
    declarations: [ // components for use in THIS module
    ],
    providers: [ // singleton services
        ApiService,
    ]
})
export class CoreModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';

@NgModule({
    declarations: [ AppComponent ],
    imports: [
        CommonModule,
        CoreModule // will provide ApiService
    ],
    providers: [],
    bootstrap: [ AppComponent ]
})
export class AppModule { }

如果在bootstrap()中列出提供程序,则无需在组件装饰器中列出它们:

import { ApiService } from '../core/api-service';

@Component({
    selector: 'main-app',
    templateUrl: '/views/main-app.html',
    // DO NOT LIST PROVIDERS HERE IF THEY ARE IN bootstrap()!
    // (unless you want a new instance)
    //providers: [ApiService]
})
export class MainAppComponent {
    constructor(private api: ApiService) {}
}

事实上,在“提供者”中列出类会创建一个新的实例,如果任何父组件已经列出它,那么子组件就不需要这样做,如果他们这样做了,他们将获得一个新实例。

 类似资料:
  • 我试图创建一个数据网格——或者在angular2中用JSON对象创建一个表格。我的问题是我不知道表中有多少列,也不知道这些列的名称。 从我目前的理解我需要定义世界卫生大会 也许一个例子会让事情变得更清楚。。。 下面是我需要在同一个表中呈现的两个JSON示例... 示例1 示例 2 这里有我的组件… 表格: 应用程序字段映射行: 注意:这是我卡住的地方! 我如何创建正确的数量的细胞和h 我没能找到任

  • 问题内容: 编辑已 解决 :如何在GoLang中创建单例DBManager类。 我参考了一些有关如何创建单例的代码示例,但是我希望在其中包含方法,并在其单例引用中对其进行调用。我的代码如下 通过新答案,我更新了此问题,包括答案。 但是我有一些疑问。如何从gorm.Create(..)进行Cathc并返回异常 问题答案: 一种方法是使用这些方法创建一个导出的接口,并使实现类型不导出。创建接口类型的全

  • 我正在快速有效地学习单例模式来创建单例类,并找到了如下创建的最佳方法。 因为我使用了语句,所以它是只读属性,必须是线程安全的,所以从目标C开始就不需要调度一次。用于将变量设置为变量。 但这如何保证在整个应用程序中只创建一个实例呢?有什么我错过的小东西吗?

  • 我需要在Swift中创建一个singleton类。谁能帮我查一下密码吗?我已经知道,单例类在创建泛型代码方面非常有用。

  • 问题内容: 这个问题不是为了讨论是否需要单例设计模式,是否是反模式,还是针对任何宗教战争,而是要讨论如何以最pythonic的方式在Python中最好地实现此模式。在这种情况下,我定义“最pythonic”表示它遵循“最小惊讶原则”。 我有多个将成为单例的类(我的用例用于记录器,但这并不重要)。当我可以简单地继承或修饰时,我不希望增加gumph来使几个类杂乱无章。 最佳方法: 方法1:装饰器 优点

  • 问题内容: 在Java中创建单例类的最佳/正确方法是什么? 我发现的实现之一是使用私有构造函数和getInstance()方法。 但是在以下测试案例中实现失败吗? 如何解决呢? 谢谢 问题答案: 根据对您的问题的评论: 我有一个包含一些键值对的属性文件,这是整个应用程序所需要的,这就是为什么我在考虑单例类。 此类将从文件中加载属性并将其保留,您可以在应用程序中的任何位置使用它 不要使用单例。您显然