Прокрутите вниз до нижней части этого поста, чтобы увидеть обходное / возможное решение.
Это, вероятно, проще просто объяснить в исходном коде с комментариями.Проблема в том, что я не могу понять, как псевдо-классы работают вместе для выполнения задачи, которую я пытаюсь выполнить (объяснение в коде ниже).
Код разбит на 3 файла: lead.js, router.js и db.js.
Приличное количество строк кода, но большая часть комментариев.
[lead.js]
var bcrypt = require('bcrypt'),
validators = require('../lib/validators'),
utility = require('../lib/utility'),
document = {};
var Lead = module.exports = function (db) {
// Save a reference to the database.
this.db = db;
// Reference initial document.
// This is totally wrong, not sure how to 'send' a variable to the constructor of a class
// when I cannot add another param. Due to how I'm importing the db model, I won't know what
// the document is until I fill out the form. I've also tried 'document' instead of 'Lead.document'.
this.document = Lead.document;
// Setup the document if it exists.
// This also doesn't work.
// Basically I want to be able to set up a document variable outside of this module (line #100),
// Then pass it to this module after filling it up with values from a form.
// Then based on what's been filled in, it would fix up (trim, convert to lower case)
// some of the values automatically and default a few values that I'm not always going to pass.
if (!document) {
var salt = bcrypt.genSaltSync(10),
hash = bcrypt.hashSync(utility.generatePassword(), salt);
// Default values.
if (!document.meta.createdAt) { this.document.meta.createdAt = Date.now(); }
if (!document.login.password) { this.document.login.password = hash; }
if (!document.login.role) { this.document.login.role = 'User'; }
// Normalize a few values.
this.document.login.email = document.login.email.toLowerCase().trim();
this.document.contact.name.first = document.contact.name.first.trim();
this.document.contact.name.last = document.contact.name.last.trim();
this.document.contact.address.street = document.contact.address.street.trim();
this.document.contact.address.city = document.contact.address.city.trim();
this.document.contact.address.state = document.contact.address.state.trim();
this.document.contact.address.zip = document.contact.address.zip.trim();
this.document.contact.phone.home = document.contact.phone.home.trim();
}
// So in regards to the above code, the end result I'm looking for is...
// I want to append some properties to the this.document reference when the document is empty (when I'm updating it, I won't set the document),
// and on new documents it will append a few default values/normalize all the fields.
};
Lead.prototype.validate = function(fn) {
var errors = [];
// Some validation rules I cut out to make this shorter.
if (errors.length) return fn(errors);
fn();
};
Lead.prototype.save = function(fn) {
this.db.collection('leads', function(err, collection) {
if (err) { fn(new Error({message: err})); }
collection.insert(this.document, function(err, result) {
return fn(err, result);
});
});
};
---
[route.js file]
var db = require('../models/db');
app.post('/register', function(req, res) {
var data = req.body.lead || {};
// Fill the document.
var document = {
meta: {
host: req.headers.host,
referer: req.headers.referer,
createdIPAddress: req.connection.remoteAddress
},
login: {
email: data.email
},
contact: {
name: {
first: data.first,
last: data.last
},
address: {
street: data.street,
city: data.city,
state: data.state,
zip: data.zip
},
phone: {
home: data.phone
}
}
};
// Write the document.
db.lead.document = document;
db.lead.validate(function(err) {
if (err) {
req.session.error = err;
return res.redirect('back');
}
db.lead.save(function(err) {
res.redirect('/register/success');
});
});
});
---
[db.js]
var mongodb = require('mongodb'),
server = new mongodb.Server('localhost', 27017),
connection = new mongodb.Db('test', server);
connection.open(function(err, db) {});
module.exports = {
lead: new (require('./lead'))(connection)
};
Когда я запускаю это, мой валидатор всегда сообщаетчто пароль пуст, что имеет смысл.Я отправляю документ изначально в класс с пустым паролем (пароль генерируется случайным образом, а не поле формы) - проблема в том, что я понятия не имею, что делать с блоком кода if (! Document) ...чтобы правильно установить this.document.
Я надеюсь, что между комментариями и кодом вы сможете понять, что я пытаюсь сделать.Я застрял на этом некоторое время.
РЕДАКТИРОВАТЬ
Я немного изменил поток, чтобы получить решение.
Вdb.js, я экспортировал соединение, а не создавал непосредственно экземпляр (и будущие модели).
В файле router.js мне требуются файл db и lead, затем передается как соединение db, так идокумент в конструкторе Лида.Пример.
var lead = new Lead(db, document);
В файле lead.js это становится так же просто, как сделать this.document = document (аналогично db).Когда я отправляю новый запрос, к документу добавляются значения, которые я не отправляю из router.js (дата создания, случайный пароль и т. Д.), И все хорошо.
Этодостойный способ справиться с этим, или есть лучший способ реорганизовать это?