首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nestjs:从带有后缀钩子的模型/实体调用服务函数

Nestjs:从带有后缀钩子的模型/实体调用服务函数
EN

Stack Overflow用户
提问于 2022-06-08 05:18:57
回答 1查看 455关注 0票数 1

在NestJS中,我必须在entity/model中使用模块服务将数据填充到elastic-search索引中。填充弹性搜索索引逻辑是用Job.service.ts编写的。

我想从模型中出现的后缀钩子中调用来自Job.service.tsJob.service.ts方法。

这是Job.ts模型/实体的代码-

代码语言:javascript
复制
import { Table, Model, Column, AutoIncrement, PrimaryKey } from "sequelize-typescript";

@Table({ schema: "job", tableName: "job" })
export class Job extends Model<Job> {
  @AutoIncrement
  @PrimaryKey
  @Column
  id: number;

  @Column
  title: string;

  @AfterCreate
  static async jobAfterCreate(instance, options) {
    // <--- need to call job service onCreate method here
  }

  @AfterUpdate
  static async jobAfterUpdate() {}

  @AfterDestroy
  static async jobAfterDestroy() {}
}

这是Job.service.ts的代码-

代码语言:javascript
复制
//imports not added
@Injectable()
export class JobService {
  constructor(
    @Inject("SEQUELIZE")
    private readonly sequelizeInstance: Sequelize,
    @Inject(forwardRef(() => ElasticsearchService))
    private readonly elasticsearchService: ElasticsearchService,
    @InjectModel(Job)
    private jobModel: typeof Job
  ) {}

  // here will write logic for updating elastic search index
  async onCreate(instance, options){
    console.log("ON CREATE INSTANCE:", instance);
    console.log("ON CREATE OPTIONS:", options);
  }
  async onDestroy(instance, options){
    console.log("ON DESTROY INSTANCE:", instance);
    console.log("ON DESTROY OPTIONS:", options);
  }
}

我尝试将服务注入Job模型,但没有奏效。而且我不能直接在模型中编写弹性搜索逻辑,因为我需要ElasticsearchService

EN

回答 1

Stack Overflow用户

发布于 2022-09-27 15:21:23

解决方案是覆盖提供程序。

向模型中注入信息的主要方法是重写注入行为。

首先,您需要添加引用模型中服务的静态属性。

我将以事件发射器为例。

你的模型类

代码语言:javascript
复制
import {Model, Table, Column, AfterCreate} from "sequelize-typescript"; 
import { EventEmitter2 } from "@nestjs/event-emitter";

@Table()
export class SomeModel extends <SomeModel> {

  // this would be your referencing
  public static EventEmitter: EventEmitter2;

  @Column
  public someColumn: string;


  @AfterCreate
  public static triggerSomeEvent(instance: SomeModel) {
    SomeModel.EventEmitter.emit('YourEvent', instance);
  } 
}

要使用模型的模块

现在,我们正在重写默认的注入过程。

代码语言:javascript
复制
import { EntitiesMetadataStorage } from '@nestjs/sequelize/dist/entities-metadata.storage';
import {
  getConnectionToken,
  getModelToken,
  SequelizeModule,
} from '@nestjs/sequelize';
import { EventEmitter2 } from '@nestjs/event-emitter';

// The provider override
const modelInjector: Provider = {
  provide: getModelToken(AccountabilityPartnerModel, DEFAULT_CONNECTION_NAME),
  useFactory: (connection: Sequelize, eventEmitter: EventEmitter2) => {
    SomeModel.EventEmitter = eventEmitter;
    if (!connection.repositoryMode) {
      return SomeModel;
    }
    return connection.getRepository(SomeModelas any);
  },
  inject: [getConnectionToken(DEFAULT_CONNECTION_NAME), EventEmitter2],
};

// Updating the meta information of sequelize-typescript package to handle connection injection in to the model overridden.

EntitiesMetadataStorage.addEntitiesByConnection(DEFAULT_CONNECTION_NAME, [
  SomeModel,
]);


// our custom module being used rather than the Sequelize.forFeature([SomeModel])
const someModelModule: DynamicModule = {
  module: SequelizeModule,
  providers: [modelInjector],
  exports: [modelInjector],
};


@Module({
  imports: [someModelModule],
  providers: [SomeService],
})
export class SomeModule {
}

像使用Sequlize.forFeature和InjectModel一样,将模型注入到服务中,如下所示。

代码语言:javascript
复制
@Injectable()
export class SomeService {
 constructor(@InjectModel(SomeModel) someModel: typeof SomeModel) {}

 public someFunction(data: any) {
   this.someModel.EventEmitter.emit('YourEvent', data);
 }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72540401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档