Гнездо. js впрыск модели? - PullRequest
0 голосов
/ 30 мая 2020

У меня есть следующий код из учебника |:

constructor(@InjectModel('User') private readonly userModel: Model<User>) {}

Где User это:

export interface User extends Document {
  readonly name: string;
  readonly age: number;
  readonly phone: string;
}

Не могли бы вы объяснить, как работает @InjectModel, что такое 'User' и почему мы пропустили Model<User>, что это значит?

Что я могу ввести, используя @InjectModel?

1 Ответ

2 голосов
/ 30 мая 2020

Хорошо, чтобы разобраться в этом, сначала мы должны признать истину, что интерфейсы не существуют во время выполнения. Так что имеющийся у вас интерфейс User полезен только во время разработки. Я постараюсь разобрать это шаг за шагом, начиная с конца строки и работая в обратном направлении.

Model<User>: Model - это тип интерфейса, предоставляемый mongoose, который позволяет нам знать что в модели, которую мы используем, есть такие методы, как find и create. Говоря Model<User>, мы говорим: «Это объект модели mon goose, который ссылается на интерфейс User. Это особенно полезно для Typescript, потому что, поскольку функции набираются с помощью универсальных типов, он знает, что возвращают такие методы, как find: массив из User объектов. Интерфейс модели на самом деле Model<T>, где T - это интерфейс, расширяющий Document (другой тип mongoose).

Что такое 'User': 'User' - строковый эквивалент имени интерфейса. Если ваш интерфейс, расширяющий Document, называется Dog, вы используете 'Dog', если Animal, вы используете 'Animal'. Причина отсутствие передачи интерфейса связано с тем, что интерфейсы не существуют во время выполнения (в отличие от классов).

Как работает @InjectModel(): Хорошо, это действительно интересная часть вопроса, на который нужно ответить. Nest работает нормально, используя токены инъекции. Обычно эти токены определяются типом введенного значения. В вашем случае Model<User>. Теперь проблема в том, что A) интерфейсы не существуют во время выполнения и B) Typescript не делает n не отражает обобщенные типы, поэтому, даже если Model был бы классом, все, что можно было бы получить, было бы Model, что недостаточно информации о том, что вводить. Итак, следующий логический шаг, который делает Nest, - это позволить пользователю предоставить токены внедрения и использовать декоратор @Inject(). Вы можете делать такие вещи, как внедрение объекта таким образом (например, информацию о конфигурации пакета). Полезно, но немного сложно работать, не создавая собственных провайдеров. Теперь введите @InjectModel(). @InjectModel() создает токен внедрения на основе строки, переданной в функцию. Этот токен похож на typeModel, где type - это фактически то, что вы передаете в функцию. Это конкретно сообщает Nest, какую модель мы вводим. Это также должно быть согласовано с поставщиком, созданным с помощью MongooseModule.forFeature(), поэтому необходимо согласовать name и значение, переданное в @InjectModel(). Обычно проще всего выровнять, если они используют то же имя строки, что и интерфейс.

...