【问题标题】:What is the Nest.js way of creating static and instance functions for a model?Nest.js 为模型创建静态和实例函数的方法是什么?
【发布时间】:2018-07-07 22:51:42
【问题描述】:

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

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

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

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

编辑:在文档的MongoDB section 中有这段代码:

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

但具体来说,这个Model&lt;Cat&gt; 部分从扩展Mongoose Document 接口的接口导入Cat。如果这个Cat 接口是一个类而不是能够执行函数(即使在编译之后),那不是更好吗?

【问题讨论】:

    标签: node.js mongodb nestjs


    【解决方案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');
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 所以我无法处理静态函数问题,但我将我需要的函数从猫鼬静态函数转移到服务函数,然后将服务注入我的另一个模块。我在文档中使用this来做,基本上是在一个模块中导出服务并在另一个模块中导入,然后注入服务并使用第一个服务的功能。顺便谢谢你的回复。
      • 很高兴您找到了解决方案 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 2023-03-04
      • 2010-10-26
      • 2020-04-11
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      相关资源
      最近更新 更多