简体   繁体   English

Angular DI 使用注入令牌用于模型类

[英]Angular DI using injection token for model class

I am trying to do something here, but not sure if it can be done.我想在这里做点什么,但不确定是否可以完成。 I want to create a model class like this:我想创建一个这样的模型类:

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;
    }
}

This is so that in a component or service I can just do a new ImageColumn(element) and it will bind the properties for me.这样在一个组件或服务中,我可以只做一个new ImageColumn(element) ,它会为我绑定属性。 Easy so far.到目前为止很容易。

Now I have a complication :) I need to bind the the backgroundImage , which is done through a service.现在我有一个并发症:) 我需要绑定backgroundImage ,这是通过服务完成的。 I updated the constructor to this:我将构造函数更新为:

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]
        );
    }
}

which is fine, but it causes an issue, because now anywhere where I use an ImageColumn I now have to pass in the contentfulService .这是很好的,但它会导致一个问题,因为现在任何地方我使用ImageColumn我现在在contentfulService通过。 I would really love to be able to pass the service without needing to supply it in the constructor.我真的很想能够传递服务而无需在构造函数中提供它。

I have done this before with services using injection tokens , so I figured I could do it here.我之前使用注入令牌的服务完成了此操作,所以我想我可以在这里完成。 I created an injection token like this:我创建了一个这样的注入令牌:

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

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

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

which I provided in my module like this:我在我的模块中提供了这样的:

@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 {}

So I figured I would be able to do this to my model:所以我想我可以对我的模型这样做:

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]
        );
    }
}

The problem is, now when i do a new ImageColumn(element) it complains that I need 2 arguments but only got 1. Does anyone know how I can get around this?问题是,现在当我做一个new ImageColumn(element)它抱怨我需要 2 个参数,但只有 1 个。有谁知道我如何解决这个问题?

I think it doesn't work that way because you didn't declare any provider for the ImageColumn .我认为它不会那样工作,因为您没有为ImageColumn声明任何提供程序 Declaring the provider would let the injector know how to obtain dependencies when you inject the ImageColumn as follows:声明提供者将使注入器知道在注入ImageColumn时如何获取依赖ImageColumn ,如下所示:

constructor (imageColumn: ImageColumn) { } 

but since you want to instantiate it manually , I'm not sure you can let Angular know how to automatically resolve the injection token.但是由于您想手动实例化它,我不确定您是否可以让 Angular 知道如何自动解析注入令牌。

What I think you can do instead is to provide the Injector when you instantiate ImageColumn .我认为您可以做的是在实例化ImageColumn时提供Injector

foo.component.ts foo.component.ts

export class FooComponent {
  constructor (private injector: Injector) { }

  ngOnInit () {
    const imgColumn = new ImageColumn(element, this.injector)
  }
}

and then in your ImageColumn 's constructor you can inject anything that has a provider declared, including that service:然后在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]
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM