Я искал решение, позволяющее работать $.bind
и $.unbind
без проблем в динамически добавленных элементах.
Поскольку on () делает трюк для присоединения событий, чтобы создать фальшивую отвязку на тех, к которым я пришел:
const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );
// unbind the click
$('body').on('click', 'button.send', function(){} );
Я думаю, что у вас такая же проблема, с которой я просто боролся. Эта проблема в вашем звонке. В нескольких учебниках вы вызываете метод .comparePassword()
из такой модели.
User.comparePassword(candidate, cb...)
Это не работает, потому что метод находится на schema
, а не на model
. Единственный способ, которым я смог вызвать метод, - найти этот экземпляр модели, используя стандартные методы запросов mongoose / mongo.
Вот важная часть моего промежуточного программного обеспечения паспорта:
passport.use(
new LocalStrategy({
usernameField: 'email'
},
function (email: string, password: string, done: any) {
User.findOne({ email: email }, function (err: Error, user: IUserModel) {
if (err) throw err;
if (!user) return done(null, false, { msg: 'unknown User' });
user.schema.methods.comparePassword(password, user.password, function (error: Error, isMatch: boolean) {
if (error) throw error;
if (!isMatch) return done(null, false, { msg: 'Invalid password' });
else {
console.log('it was a match'); // lost my $HÏT when I saw it
return done(null, user);
}
})
})
})
);
Итак, я использовал findOne({})
, чтобы получить экземпляр документа, а затем должен был получить доступ к методам схемы, вставив в свойства схемы документ user.schema.methods.comparePassword
. Несколько различий, которые я заметил:
instance
, а ваш метод static
. Я уверен, что существует аналогичная стратегия доступа к методу. comparePassword()
. возможно, это не обязательно для статики, но мне не удалось получить доступ к this.password
У меня была такая же проблема, как и у вас, а затем, наконец, удалось разрешить ее после прочтения документации в типизированных файлах TS mongoose (о которой я раньше не знал, и я не уверен, как долго документы были вокруг), в частности в этом разделе . Я понимаю, что это старый вопрос очень , но я думал, что это может помочь потерянному человеку в будущем. Изменить: я прочитал дату существующего ответа как март 2014 года, а не 14 марта.
Что касается вашего дела, вы захотите следовать аналогичный шаблон, который у вас есть, хотя вам нужно изменить несколько вещей в обоих файлах.
Файл IUser
IUser
в IUserDocument
. Document
из mongoose. Document
. Файл модели
IUser
на IUserDocument
, включая путь к модулю, если вы переименуете файл. IUserModel
к IUser
. IUser
простирается от, от IUserDocument, Document
до IUserDocument
. IUserModel
, который простирается от Model<IUser>
. IUserModel
. User
с Model<IUserModel>
на IUserModel
, так как IUserModel
теперь расширяет Model<IUser>
. <IUserModel>
на <IUser, IUserModel>
. Вот как выглядит ваш файл модели с этими изменениями:
import * as bcrypt from 'bcryptjs';
import { Document, Schema, Model, model } from 'mongoose';
import { IUserDocument } from '../interfaces/IUserDocument';
export interface IUser extends IUserDocument {
comparePassword(password: string): boolean;
}
export interface IUserModel extends Model<IUser> {
hashPassword(password: string): boolean;
}
export const userSchema: Schema = new Schema({
email: { type: String, index: { unique: true }, required: true },
name: { type: String, index: { unique: true }, required: true },
password: { type: String, required: true }
});
userSchema.method('comparePassword', function (password: string): boolean {
if (bcrypt.compareSync(password, this.password)) return true;
return false;
});
userSchema.static('hashPassword', (password: string): string => {
return bcrypt.hashSync(password);
});
export const User: IUserModel = model<IUser, IUserModel>('User', userSchema);
export default User;
И ваш (недавно переименованный) модуль ../interfaces/IUserDocument
будет выглядеть так:
import { Document } from 'mongoose';
export interface IUserDocument extends Document {
email: string;
name: string;
password: string;
}
Я не вижу ваш интерфейс IUser, однако я подозреваю, что вы не включили в него методы. EG
export interface IUser {
email: string,
hash: string,
salt: string,
setPassword(password: string): void,
validPassword(password: string): boolean,
generateJwt(): string
}
машинописный текст затем распознает ваши методы и перестанет жаловаться
userSchema.methods.functionName = function(){}
. Я не уверен, что это влияет на вас, но может быть.
– xerotolerant
27 February 2017 в 19:20
user.comparePassword
? Возможно, это устранит вашу проблемуthis.password
( stackoverflow.com/questions/42415142/… ), поскольку у меня возникла аналогичная проблема. – Cludch 16 March 2017 в 11:58User.schema.statics.hashPassword()
. – Jackpile 30 May 2017 в 17:42