Давайте на минуту вернемся к предыдущему посту, где мы начали загружать некоторые базовые приложения Backbone.js. Теперь это очень просто, просто собирая все данные и отправляя данные на сервер.
Любая надежная система практически невозможна без проверки. Если какое-либо поле является обязательным или должно соответствовать какому-либо конкретному правилу, оно должно быть проверено как можно скорее, и информация о проверке должна отображаться пользователю. Затем пользователь применяет исправления и повторно представляет данные.
В случае модели «Обратная связь», мы заинтересованы, чтобы пользователь всегда вводил свою электронную почту и сообщение обратной связи. Backbone.js предоставляет очень простой способ проверки моделей. Если модель требует проверки, она должна реализовать метод проверки .
Итак, давайте расширим нашу модель методом validate.
var Feedback = Backbone.Model.extend({
    url: '/feedback',
    defaults: {
        'email': '',
        'website': '',
        'feedback': ''
    },
    validate: function (attrs) {
        if (!attrs.email) {
            return 'Please fill email field.';
        }
        if (!attrs.feedback) {
            return 'Please fill feedback field.';
        }
    }
});
Как видите, в случае отсутствия электронной почты или обратной связи, мы просто возвращаем строку с сообщением об ошибке.
Чтобы лучше понять, что происходит, давайте рассмотрим некоторый фрагмент кода из инфраструктуры Backbone.js. А именно, для `_validate` метода` Backbone.Model`, который фактически отвечает за проверку.
_validate: function(attrs, options) {
    if (options.silent || !this.validate) return true;
    attrs = _.extend({}, this.attributes, attrs);
    var error = this.validate(attrs, options);
    if (!error) return true;
    if (options && options.error) {
       options.error(this, error, options);
    } else {
        this.trigger('error', this, error, options);
    }
    return false;
}
Вы можете видеть, что если `validate` возвращает либо undefined, либо null, либо false,` _validate` просто возвращает true — это значит, что модель действительна. В противном случае он проверил бы, инициализирована ли функция `options.error`, и вызвал бы ее, если не было вызвано событие модели` error`.
Во время сохранения модели мы обычно предоставляем как обратные вызовы, так и сообщения об ошибках. Это означает, что обратный вызов ошибки будет вызван, если модель не пройдет требования валидации. Внутри обратного вызова мы могли бы решить, что делать с ошибками. Прямо сейчас, давайте просто сделаем предупреждение.
var options = {
    success: function () {
        alert('Thanks for the feedback!');
    },
    error: function (model, error) {
        alert(error);
    }
};
var feedback = {
    email: this.$('#email').val(),
    website:  this.$('#website').val(),
    feedback: this.$('#feedback').val()
};
this.model.save(feedback, options);
Обратите внимание, что обратный вызов `error` получает саму модель в качестве первого аргумента, а объект ошибки (один возвращается из метода` validate`) в качестве второго аргумента. Давайте попробуем этот код: оставьте поля электронной почты и обратной связи пустыми и нажмите кнопку отправки.
Однако у такой реализации есть несколько недостатков. Во-первых, окна `alert` ужасны, во-вторых, если пользователь исправляет электронную почту, в следующий раз, когда он нажимает кнопку отправки, появляется следующее предупреждение с другим сообщением. Это ужасный UX, так что давайте исправим это.
Таким образом, мы должны сделать 2 вещи: собрать все ошибки во время проверки и применить к ним несколько хороших стилей.
Вместо того, чтобы возвращать простые строки, мы будем возвращать массив объектов, содержащий имя провала, поле и сообщение.
validate: function (attrs) {
    var errors = [];
    if (!attrs.email) {
        errors.push({name: 'email', message: 'Please fill email field.'});
    }
    if (!attrs.feedback) {
        errors.push({name: 'feedback', message: 'Please fill feedback field.'});
    }
    return errors.length > 0 ? errors : false;
}
Измените параметры метода `save`, чтобы отображать ошибки, если возникла какая-либо ошибка, и скрывать ошибки, если сохранение прошло успешно.
var me = this;
var options = {
    success: function () {
        me.hideErrors();
    },
    error: function (model, errors) {
        me.showErrors(errors);
    }
};
И реализовать 2 простых метода:
showErrors: function(errors) {
    _.each(errors, function (error) {
        var controlGroup = this.$('.' + error.name);
        controlGroup.addClass('error');
        controlGroup.find('.help-inline').text(error.message);
    }, this);
},
hideErrors: function () {
    this.$('.control-group').removeClass('error');
    this.$('.help-inline').text('');
}
Давайте проверим код. Поскольку все поля оставлены пустыми, это будет выглядеть так:
По мере заполнения полей и отправки формы все ошибки удаляются из формы.
Выводы
Это был очень простой стиль «шаг за шагом», приближающийся к валидации модели. Я бы мог это, проверка «из коробки». Даже если это очень полезно, есть много разных подходов, чтобы сделать вещи лучше. Исходный код доступен на github .
Оставайтесь с нами для следующих шагов ребенка Backbone.js скоро.

