在Angular 6中生成服务时,为Injectable decorator提供的目的是什么?

在Angular 6中生成服务时,为Injectable decorator提供的目的是什么?,angular,angular6,Angular,Angular6,在Angular CLI中生成服务时,它正在为可注入装饰器添加具有默认值为“root”的“provided in”属性的额外元数据 @Injectable({ providedIn: 'root', }) providedIn到底做什么?我假设这使服务像“全局”类型的单例服务一样可用于整个应用程序,但是,在AppModule的提供者数组中声明这样的服务不是更干净吗 更新: 对于其他人来说,下面的段落也提供了另一个很好的解释,特别是如果您只想为功能模块提供服务 现在有了一种新的推荐方式,可以

在Angular CLI中生成服务时,它正在为可注入装饰器添加具有默认值为“root”的“provided in”属性的额外元数据

@Injectable({
  providedIn: 'root',
})
providedIn到底做什么?我假设这使服务像“全局”类型的单例服务一样可用于整个应用程序,但是,在AppModule的提供者数组中声明这样的服务不是更干净吗

更新:

对于其他人来说,下面的段落也提供了另一个很好的解释,特别是如果您只想为功能模块提供服务

现在有了一种新的推荐方式,可以直接注册提供者 在
@Injectable()
decorator内部,使用中提供的新
属性它接受
'root'
作为您的应用程序的值或任何模块 应用当您使用
'root'
时,您的
可注入的
将 在应用程序中注册为singleton,您不需要 将其添加到根模块的提供程序。同样,如果您使用
提供在:UsersModule
中,
可注入的
注册为
UsersModule的提供程序
,而不将其添加到的
提供程序
模块。”-

更新2:

经过进一步调查,我决定只在“根目录”中提供
是有用的


如果您希望
在根模块以外的任何模块中提供
服务,那么最好在功能模块的装饰器中使用
提供程序
数组,否则您将受到循环依赖的困扰。这里将进行有趣的讨论-

如果您使用providedIn,则将注册可注入的作为模块的提供程序,而不将其添加到模块的提供程序中

服务本身是CLI生成的一个类,这是 用@Injectable修饰。默认情况下,此装饰器已配置 使用providedIn属性,该属性为服务创建提供程序。 在这种情况下,providedIn:'root'指定服务应该是 在根部注射器中提供


providedIn告诉Angular,根注入器负责创建您的服务实例。以这种方式提供的服务将自动提供给整个应用程序,不需要在任何模块中列出

服务类可以充当它们自己的提供者,这就是为什么在@Injectable decorator中定义它们是您所需要的全部注册。

根据:

在@Injectable()元数据中注册提供程序也允许 Angular通过从已编译的应用程序中删除服务来优化应用程序 应用程序(如果未使用)


providedIn:'root'
是自Angular 6:

  • 该服务将在应用程序范围内作为一个单例提供,无需将其添加到模块的提供者数组(如Docs中的Angular)

    什么是可注射装饰剂

    将类标记为可供Injector创建

    import { Injectable } from '@angular/core';
    
    @Injectable({
      providedIn: 'root',
    })
    export class UserService {
    }
    
    服务本身是CLI生成的类,并用@Injectable()修饰

    providedIn到底做什么

    通过将其与@NgModule或其他InjectorType关联,或通过指定应在“根”注入器中提供此注入器来确定哪些注入器将提供可注射,这将是大多数应用程序中的应用程序级注入器

    providedIn: Type<any> | 'root' | null
    
    此方法是首选方法,因为如果没有注入任何内容,它将启用服务的树抖动(树抖动是构建过程中的一个步骤,从代码库中删除未使用的代码)

    如果无法在服务中指定应提供服务的模块,还可以在模块中声明服务的提供程序:

    import { NgModule } from '@angular/core';
    import { UserService } from './user.service';
    
    @NgModule({
      providers: [UserService],
    })
    export class UserModule {
    }
    

    请参见

    我想通过添加示例来扩展它

    如果您只使用可注入装饰器,而不在
  • 属性中提供
    ,例如

    @Injectable()
    
    然后,您必须将服务的名称写入相应模块的
    提供者
    数组中

    像这样,

    data.service.ts↴

    import { Injectable } from '@angular/core';
    
    @Injectable()
    export class DataService {
        constructor() {}
    
        // Code . . .
    }
    
    import { Injectable } from '@angular/core';
    
    @Injectable({
        providedIn: 'root',
    })
    export class DataService {
        constructor() {}
    
        // Code . . .
    }
    
    app.module.ts↴

    import { AppComponent } from './app.component';
    import { DataService } from './core/data.service';
    
    @NgModule({
        declarations: [AppComponent],
        providers: [DataService],    // ⟵ LOOK HERE WE PROVIDED IT
        imports: [...],
        bootstrap: [AppComponent],
    })
    export class AppModule {}
    
    import { AppComponent } from './app.component';
    import { DataService } from './core/data.service';
    
    @NgModule({
        declarations: [AppComponent],
        providers: [],
        imports: [...],
        bootstrap: [AppComponent],
    })
    export class AppModule {}
    
    但是,如果使用“根目录”中提供的
    ,如下所示:

    data.service.ts↴

    import { Injectable } from '@angular/core';
    
    @Injectable()
    export class DataService {
        constructor() {}
    
        // Code . . .
    }
    
    import { Injectable } from '@angular/core';
    
    @Injectable({
        providedIn: 'root',
    })
    export class DataService {
        constructor() {}
    
        // Code . . .
    }
    
    然后我们的模块将如下所示:

    app.module.ts↴

    import { AppComponent } from './app.component';
    import { DataService } from './core/data.service';
    
    @NgModule({
        declarations: [AppComponent],
        providers: [DataService],    // ⟵ LOOK HERE WE PROVIDED IT
        imports: [...],
        bootstrap: [AppComponent],
    })
    export class AppModule {}
    
    import { AppComponent } from './app.component';
    import { DataService } from './core/data.service';
    
    @NgModule({
        declarations: [AppComponent],
        providers: [],
        imports: [...],
        bootstrap: [AppComponent],
    })
    export class AppModule {}
    
    请看,这次我没有在
    提供者
    数组中添加
    数据服务
    ,因为不需要它

    良好做法 这可能会派上用场,从

    在服务的@Injectable装饰器中使用应用程序根注入器提供服务。

    为什么?角式喷油器是分层的

    为什么?当您向根注入器提供服务时,该服务的实例将在每个需要该服务的类中共享和可用。当服务共享方法或状态时,这是理想的选择

    为什么?当您在服务的@Injectable decorator中注册服务时,Angular CLI生产版本使用的优化工具可以执行树抖动并删除应用程序未使用的服务

    为什么?当两个不同的组件需要不同的服务实例时,这并不理想。在这种情况下,最好在需要新实例和单独实例的组件级别提供服务


    谢谢Sajeetharan。好吧,这听起来像是一种新的快捷方式,可以指定服务应该提供在哪里。我想我最初的偏好应该是查看模块的提供者列表,以查看所有声明为提供者的服务,而不是仔细阅读ProvidedIn标记的分散代码库……()安格尔有什么理由加上这个吗