正在导入Injectables和Angular Services



我正在学习Angular中的Injectables和Services,我不清楚关于Injectable的某些导入和默认特性。具体来说,Angular中的服务应该在什么时候:

  1. 有@Injectables标签吗?我看到过一篇没有使用它的博客文章。当你去掉它时会发生什么?去掉这个标签会如何改变服务的行为方式?

  2. 是否在app.module的providers数组中声明?

  3. 是否在单个组件的提供程序数组中声明,而不是在app.module中声明?

  4. 当使用@Injectables标记时,providedIn关键字的默认值是什么?如果您的服务中没有定义这个关键字,那么应该对关键字的值和服务的范围进行什么假设?

  5. 假设我有一个具有以下特征的服务(我们称之为DummyService):具有@Injectables标记,不定义providedIn,不在任何提供者数组中声明(既不是app.module,也不是任何单个组件)。

    • 5.a)由于没有指定providedIn,并且该服务没有在任何提供程序数组中声明,因此该服务可以与同级组件共享吗
    • 5.b)当从导入DummyService的组件调用DummyServices时,与这些用例有什么区别:
DummyService.addToList("Stacy");

constructor(private _dummyservice: DummyService){} 
ngOnInit(){
this.dummyservice.addToList("Stacy");
}

将更深入地回答。。。

  1. @Injectable装饰器向注入器注册服务。将服务标记为可注入意味着可以将其他服务注入该服务。如果您省略它,您可以安全地提供和注入服务,但如果您试图注入服务,angular将向您抛出错误。不过,通常情况下,最佳做法是将所有服务标记为@Injectable(),无论您是否向它们注入。

  2. 目前使用providedIn: 'root'是注册单例服务的首选方式,或者您只想在应用程序范围内拥有一个共享实例的服务,这或多或少相当于将其添加到app.module中的providers数组中。但是,如果您需要使用像工厂提供程序这样的特殊提供程序,则需要使用app.moduleproviders数组。providedIn: 'root'对于延迟加载模块也很有用,因为angular的早期迭代在延迟加载模块中遇到了一些问题,因为它们自己的提供程序阵列获得了不同的服务副本,这些副本意味着是单体。CCD_ 6选项很好地解决了这个问题。

  3. 在组件中提供意味着该组件将获得给定服务的自己的实例,并且该组件的所有子级都将接收给定服务的该实例。如果您仅在app.module(或root)级别提供,那么所有组件都将在应用程序范围内接收相同的服务。如果合适的话,您可以在根AND组件级别提供,但您应该知道它的作用(常见的情况是某种全局与本地警报服务)。

  4. ";默认";提供什么都没有。如果省略它,则必须在提供者数组中适当地声明服务才能注入和使用它。在将其声明为根提供的服务或将其放入提供者数组之前,它没有作用域。

  5. 如果不提供该服务,则无法注入,完全停止。问题5a和5b都是不相关的,因为不能注入服务。您的示例似乎是以静态方式访问服务方法,这通常是个坏主意。重要的是实际注入您打算使用的服务,以使依赖项注入对您的应用程序有用。

1.)@Injectable装饰器,它将类标记为可提供并作为依赖项注入。(发件人:https://angular.io/api/core/Injectable)

表示此类可以与Injector一起使用。但是Angular实际上不能在任何地方注入它,除非您使用该服务的提供者配置Angular依赖项注入器。这可以在@Injectable@NgModule()@Component()内部完成

2.)app.module的providers数组中声明服务与@Injectable({providedIn: 'root'})相同。你不需要两者都做。使用providedIn是目前推荐的新方法

3.)Angular中的服务可以是singleton,因此如果您在app.module中提供服务,您可以在任何地方访问该服务,并且它始终是同一个实例。如果您在组件级别上提供服务,那么每个组件实例都会获得自己的服务实例。

@Component({providers: [DummyService], ...})
export class FooComponent {
constructor(
private readonly _dummyService: DummyService,
) {}
}

基本上与相同

@Component(...)
export class FooComponent {
private readonly _dummyService = new DummyService();
constructor() {}
}

只是后者不使用Angular的DI。

4.){providedIn: 'root'},如果未设置providedIn,则必须通过提供者阵列设置服务。

5.)Angular DI无法重新提供您的服务。请参见此处:https://stackblitz.com/edit/angular-ivy-c48sfa?file=src/app/app.module.ts

@Injectable({
providedIn: 'root',
})

上面的代码告诉angular,获取这个类并将其加载到注入器/容器中,该注入器或容器可以被认为是组件顶部的容器。Angular将自动为我们创建每个服务的单个实例。我们不像那样创建自己

dummy= new DummyService()

angular将为我们提供它,并使其可用于注射器容器内的所有不同组件。这将使代码可重用。

因此,每当有人在任何组件中调用DummyService时,angular都会发送DummyService的实例。您可以在组件类的构造函数中手动创建它。

  • 依赖注入的目标是使测试更容易,并使代码可重用

如果你去浏览器并检查编译器,到达定义类的那一行,你会看到这样的东西:

AppComponent.ctorParameters=() ⇒  {type:_dummy_service__WEBPACK_IMPORTED_MODULE_2__[“DummyService” ]} ]

typescript文件中的所有代码都在浏览器中执行之前由typescript编译器进行处理。然后webpack接管了所有的类型,所有的注释,所有的公共和私有的东西都被撕掉了。因为你的浏览器不知道如何理解打字。类组件构造函数参数也像上面一样作为一个新属性被删除。

相关内容

  • 没有找到相关文章

最新更新