2

这样的事情是否存在或者我是否遵循标准的猫鼬程序?

我阅读了文档,我昨天花了一整天的时间,但我只能找到将功能放置在服务组件中的相关文档。这不是有效的,好像我想在服务组件之外使用静态模型函数(例如,自定义装饰器),因为 DI 是私有的,所以它不会到达它。

我会在 Github 上为文档请求创建一个问题,但我担心我可能忽略了一些东西。

编辑2:请不要更改帖子的标题。“巢”不是“最佳”的拼写错误。它指的是一个名为 Nest.js 的 Node.js 框架。(请参阅帖子标签和参考文档链接)

编辑:在文档的MongoDB 部分,有这段代码:

constructor(@InjectModel(CatSchema) private readonly catModel: Model<Cat>) {}

但具体来说,这部分是从扩展 Mongoose接口的接口Model<Cat>导入的。如果这个接口是一个具有功能的类而不是一个类(即使在编译之后)不是更好吗?CatDocumentCat

4

2 回答 2

1

我使用以下方法:

定义架构时,将静态方法添加到 Mongoose 架构:

UserSchema.methods.comparePassword = async function(candidatePassword: string) {
  return await bcrypt.compare(candidatePassword, this.password);
};

还要在对象的接口定义中包含该方法:

export interface User {
  firstName: string;
  ...
  comparePassword(candidatePassword: string): Promise<boolean>;
}

以及 UserDocument 界面

export interface UserDocument extends User, Document { }

所以现在我的用户服务:

export class UsersService {
  constructor(@InjectModel(Schemas.User) private readonly userRepository: Model<UserDocument>,
              private readonly walletService: WalletsService,
              @Inject(Modules.Logger) private readonly logger: Logger) {}

  async findByEmail(email: string): Promise<UserDocument> {
    return await this.userRepository.findOne({ email }).select('password');
  }
  ...
}

为了将这一切联系在一起,当用户尝试登录时,Auth 服务通过 id 检索用户对象,并调用该用户对象的 comparePassword 实例方法:

@Injectable()
export class AuthService {
  constructor(
    private readonly usersService: UsersService,
    private readonly jwtService: JwtService,
  ) { }

  async signIn({ email, password }: SignInDto): Promise<LoginResponse> {
    const user = await this.usersService.findByEmail(email);
    if (!user) { throw new UnauthorizedException('Invalid Username or Password'); }

    if (await user.comparePassword(password)) {
      const tokenPayload: JwtPayload = { userId: user.id };
      const token = this.jwtService.sign(tokenPayload);
      return ({ token, userId: user.id, status: LoginStatus.success });
    } else {
      throw new UnauthorizedException('Invalid Username or Password');
    }
  }
}
于 2018-12-30T21:10:19.820 回答
0

@InjectModel()是注入注册组件的辅助装饰器。您始终可以直接使用模型类,而不是通过构造函数注入它。多亏了这一点,您可以在任何地方使用模型(但我不确定自定义装饰器是否是正确的选择)。另外,Model<Cat>这里是多余的。您可以将此类型替换为适合您的用例的任何其他类型,例如,typeof X如果您想调用静态函数。

于 2018-02-04T14:53:10.170 回答