【问题标题】:Angular DI using injection token for model classAngular DI 使用模型类的注入令牌
【发布时间】:2020-11-22 10:54:37
【问题描述】:

我正在尝试在这里做一些事情,但不确定是否可以完成。 我想创建一个这样的模型类:

import { Inject } from '@angular/core';
import {
    Element,
    Image,
} from '@situlive/situ-angular-components/contentful';

export class ImageColumn {
    title: string;
    backgroundImage: Image;
    backgroundImageAlignment: string;

    constructor(
        element: Element
    ) {
        this.title = element.fields.title;
        this.backgroundImageAlignment = element.fields.backgroundImageAlignment;
    }
}

这样在组件或服务中我可以只做一个new ImageColumn(element),它会为我绑定属性。 到目前为止很容易。

现在我有一个复杂的情况:) 我需要绑定 backgroundImage,这是通过服务完成的。我将构造函数更新为:

import { Inject } from '@angular/core';
import {
    ContentfulService,
    Element,
    Image,
} from '@situlive/situ-angular-components/contentful';

export class ImageColumn {
    title: string;
    backgroundImage: Image;
    backgroundImageAlignment: string;

    constructor(
        contentfulService: ContentfulService,
        element: Element
    ) {
        this.title = element.fields.title;
        this.backgroundImageAlignment = element.fields.backgroundImageAlignment;

        this.backgroundImage = this.contentfulService.createImage(
            element.fields.backgroundImage[0]
        );
    }
}

这很好,但它会导致一个问题,因为现在我在使用 ImageColumn 的任何地方都必须传入 contentfulService。我真的很希望能够传递服务而不需要在构造函数中提供它。

我之前使用 注入令牌 的服务已经做到了这一点,所以我想我可以在这里做到这一点。 我创建了一个这样的注入令牌:

import { InjectionToken } from '@angular/core';

import { ContentfulService } from '@situlive/situ-angular-components/contentful';

export const CONTENTFUL_SERVICE = new InjectionToken<ContentfulService>(
  'CONTENTFUL_SERVICE'
);

我在我的模块中这样提供:

@NgModule({
  imports: [
    CommonModule,
    HttpClientModule,
    RouterModule,

    AuthModule.forRoot(environment.auth0),
    ContentfulModule.forRoot(environment.contentful),
  ],
  declarations: [FooterComponent, HeaderComponent],
  exports: [FooterComponent, HeaderComponent],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: BearerInterceptor,
      multi: true,
    },
    {
      provide: CONTENTFUL_SERVICE,
      useClass: ContentfulService,
      multi: true,
    },
  ],
})
export class CoreModule {}

所以我想我可以对我的模型执行此操作:

import { Inject } from '@angular/core';
import {
    ContentfulService,
    Element,
    Image,
} from '@situlive/situ-angular-components/contentful';

import { CONTENTFUL_SERVICE } from '../contentful-service.token';

export class ImageColumn {
    title: string;
    backgroundImage: Image;
    backgroundImageAlignment: string;

    constructor(
        @Inject(CONTENTFUL_SERVICE) private contentfulService: ContentfulService,
        element: Element
    ) {
        this.title = element.fields.title;
        this.backgroundImageAlignment = element.fields.backgroundImageAlignment;

        this.backgroundImage = this.contentfulService.createImage(
            element.fields.backgroundImage[0]
        );
    }
}

问题是,现在当我执行new ImageColumn(element) 时,它抱怨我需要 2 个参数,但只有 1 个。 有谁知道我该如何解决这个问题?

【问题讨论】:

    标签: angular dependency-injection injection-tokens


    【解决方案1】:

    我认为它不起作用,因为您没有为ImageColumn 声明任何提供者。声明提供者将使 injector 在您注入 ImageColumn 时知道如何获取依赖项,如下所示:

    constructor (imageColumn: ImageColumn) { } 
    

    但由于您想手动实例化它,我不确定您是否可以让 Angular 知道如何自动解析注入令牌。

    我认为您可以做的是在实例化 ImageColumn 时提供 Injector

    foo.component.ts

    export class FooComponent {
      constructor (private injector: Injector) { }
    
      ngOnInit () {
        const imgColumn = new ImageColumn(element, this.injector)
      }
    }
    

    然后在 ImageColumn 的构造函数中,您可以注入任何声明了提供程序的东西,包括该服务:

    class ImageColumn {
      constructor (private element: any, private injector: Injector) {
        this.contentfulService = this.injector.get(ContentfulService);
    
        /* ... */
    
        this.backgroundImage = this.contentfulService.createImage(
          element.fields.backgroundImage[0]
        );
      }
    }
    

    【讨论】:

    • 我会接受这个作为答案;我知道你可以做到这一点,但老实说,最好只注入服务
    猜你喜欢
    • 2021-09-02
    • 1970-01-01
    • 2017-06-27
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    相关资源
    最近更新 更多