На Meteor, как я могу проверить с Collection2 на стороне клиента?
Я всегда использую методы для вставки, обновления и удаления. Вот как мой код выглядит сейчас:
Сторона клиента
Template.createClient.events({
'submit form': function(event, tmpl) {
e.preventDefault();
var client = {
name: event.target.name.value,
// .... more fields
}
var validatedData = Clients.validate(client);
if (validatedData.errors) {
// Display validation errors
return;
}
Meteor.call('createClient', validatedData.client, function(error) {
if (error)
// Display error
});
}
});
Клиентская и серверная сторона:
Clients = new Mongo.Collection("clients");
Clients.validate = function(client) {
// ---- Clean data ----
client.name = _.str.trim(client.name);
// .... more fields clean
// ---- Validate data ---
var errors = [];
if (!client.name)
errors.push("The name is required.");
// .... more fields validation
// Return and object with errors and cleaned data
return { errors: _.isEmpty(errors) ? undefined : errors, client: client };
}
Meteor.methods({
'createClient': function (client) {
// --- Validate user permisions ---
// If server, validate data again
if (Meteor.isServer) {
var validatedData = Clients.validate(client);
if (validatedData.errors)
// There is no need to send a detailed error, because data was validated on client before
throw new Meteor.Error(500, "Invalid client.");
client = validatedData.client;
}
check(client, {
name: String,
// .... more fields
});
return Clients.insert(client);
}
});
Meteor.call выполняется на стороне клиента и сервера, но у Meteor нет способа остановить запуск на стороне сервера, если проверка на стороне клиента не удалась (или, по крайней мере, я не знаю как). С этим шаблоном я избегаю отправки данных на сервер с Meteor.call, если проверка не удалась.
Я хочу начать использовать Collection2, но не могу понять, как получить тот же шаблон. Все примеры, которые я нашел, включают в себя использование прямой вставки и обновления на стороне клиента и Allow/Deny для управления безопасностью, но я хочу придерживаться Meteor.call.
Я нашел в документации, что я могу проверить перед вставкой или обновлением, но я не знаю, как заставить это работать:
Books.simpleSchema().namedContext().validate({title: "Ulysses", author: "James Joyce"}, {modifier: false});
Я знаю пакет автоформ, но я хочу пока избегать этого пакета.
Как я могу проверить с Collection2 на стороне клиента перед отправкой данных на сторону сервера с Meteor.call? Мой шаблон неправильный или несовместимый с Collection2, и мне нужно сделать это по-другому?
2 ответа
Менее чем в 30 строках вы можете написать свой собственный, полнофункциональный пакет проверки для Collection2. Давайте пройдемся по примеру:
"use strict"; //keep it clean
var simplyValid = window.simplyValid = {}; //OK, not that clean (global object)
simplyValid.RD = new ReactiveDict(); //store error messages here
/**
*
* @param data is an object with the collection name, index (if storing an array), and field name, as stored in the schema (e.g. 'foo.$.bar')
* @param value is the user-inputted value
* @returns {boolean} true if it's valid
*/
simplyValid.validateField = function (data, value) {
var schema = R.C[data.collection]._c2._simpleSchema; //access the schema from the local collection, 'R.C' is where I store all my collections
var field = data.field;
var fieldVal = field.replace('$', data.idx); //make a seperate key for each array val
var objToValidate = {};
var dbValue = schema._schema[field].dbValue; //custom conversion (standard to metric, dollars to cents, etc.) IGNORE
if (dbValue && value) value = dbValue.call({value: value}); //IGNORE
objToValidate[field] = value; //create a doc to clean
schema.clean(objToValidate, {removeEmptyStrings: false}); //clean the data (trim, etc.)
var isValid = schema.namedContext().validateOne(objToValidate, field, {extendedCustomContext: true}); //FINALLY, we validate
if (isValid) {
simplyValid.RD.set(fieldVal, undefined); //The RD stores error messages, if it's valid, it won't have one
return true;
}
var errorType = schema.namedContext()._getInvalidKeyObject(field).type; //get the error type
var errorMessage = schema.messageForError(errorType, field); //get the message for the given error type
simplyValid.RD.set(fieldVal, errorMessage); //set the error message. it's important to validate on error message because changing an input could get rid of an error message & produce another one
return false;
};
simplyValid.isFieldValid = function (field) {
return simplyValid.RD.equals(field, undefined); //a very cheap function to get the valid state
};
Не стесняйтесь раскалывать нужные вам кусочки и отвечать на любые ваши вопросы.
Вы можете отправить схему клиенту и проверить ее перед отправкой на сервер. Если вы хотите использовать коллекцию ", вам нужно присоединить схему к коллекции и использовать insert
это то, что вы не хотите. Поэтому лучшим вариантом для вашего сценария является отправка схемы клиенту и ее использование для проверки.
Также пересмотрите возможность использования мини-монго вместо использования методов для всего, это сэкономит вам много времени и не будет думать, что ваше приложение защищено просто потому, что вы используете методы.