Angular DI中对@Inject和Injectable的需求是什么?

时间:2017-08-17 12:22:56

标签: javascript angular dependency-injection

constructor(private smartphoneService: smartphoneService) { }

我可以在没有错误的情况下运行代码。但是为什么我们在服务,管道等上使用@Inject和Injectable。任何少数使用..?为什么以及在哪里我们需要使用这个.. ??

    import { Injectable } from '@angular/core';
    import {SmartphoneListComponent} from './smartphone-list/smartphone-list.component';

    @Injectable()

    export class smartphoneService{
      smartphones: any = [
                  {id: '1', name: 'iPhone6', status: 'active'},
                  {id: '2', name: 'iPhone6S', status: 'active'},
                  {id: '3', name: 'iPhone7', status: 'active'},
                  {id: '4', name: 'iPhone7Plus', status: 'active'},
                  {id: '5', name: 'iPhoneX', status: 'future'}
                ];

        constructor() { }
}

3 个答案:

答案 0 :(得分:0)

@Injectable

您需要在注入依赖项的服务上使用@Injectable,并使用类类型注入:

@Injectable()
class A { constructor (b: B) {} }

class C { constructor (c: C) {} }

如果服务没有注入依赖项,则不需要使用@Injectable

class A { constructor () {} }

class C { constructor (c: C) {} }

或者它是使用@Inject装饰器注入的:

class A { constructor (b: B) {} }

class C { constructor (@Inject(C) c) {} }

基本上,您可以使用任何装饰器而不是@Injectable。这将有效:

function Custom(target) {}

@Custom
class A { constructor (b: B) {} }

class C { constructor (c: C) {} }

这是因为当Angular试图理解要传递给类构造函数的注入事项时,它会使用类的元数据。只有当emitDecoratorMetadata: true中有tsconfig.json并且任何装饰器应用于某个类时,此元数据才会由TypeScript生成。

@注入

当您明确使用@Inject装饰器时,Angular不会使用TypeScript生成的元数据,因此如果您使用@Injectable,则不需要应用@Inject@Inject最常见的用例是通过引用注入对象,而不是键入:

const token1 = new InjectionToken('my');
const token2 = 's';

class C { constructor (@Inject(token1) t1, @Inject(token2) t2) {} }

答案 1 :(得分:0)

Angular文档提供了您的问题的答案:

  

@Injectable()将一个类标记为可用于实例化的注入器。一般来说,在尝试实例化未标记为@Injectable()的类时,注入器会报告错误。

除此之外,他们还建议将注释放在每个服务类上,原因如下:

  • 未来验证:稍后添加依赖项时无需记住@Injectable()。
  • 一致性:所有服务都遵循相同的规则,您不必怀疑为何缺少装饰器。

以下是文档的链接: https://angular.io/guide/dependency-injection#why-injectable

答案 2 :(得分:0)

组件由Angular实例化,它已经被@Component修饰。添加@Inject是隐含的。那么为什么要强迫开发人员使用@Inject for Components?

OTOH如果Angular需要@Inject为它的构造函数那么具有未注入的构造函数arg意味着什么?它变得毫无意义arg,因为它没有注入,Angular必须创建实例?然后我们必须强制每个参数都标记为@inject。

服务看起来像一流的JavaScript类。域实体类也是如此。但是服务不带状态,因此在同一服务类周围挂起几个实例是没有意义的。 OTOH实体可以是同一类的多个实例。 现在,由于这两类类看起来相似,我们如何告诉Angular哪个类是Singleton,最重要的是我们如何告诉Angular我们需要在某处注入实例。 在DI我们说我想要一个类的实例。