Validation libraries

Основы валидации в Backbone.js

Backbone.js предоставляет минималистичный каркас для построения клиентских приложений, но не включает встроенную мощную систему валидации. Основной инструмент для проверки данных в Backbone — метод validate, который можно определить в модели. Этот метод вызывается автоматически при вызове методов save или set, если указана опция validate: true.

Сигнатура метода validate:

var User = Backbone.Model.extend({
  validate: function(attrs) {
    var errors = {};
    if (!attrs.name) {
      errors.name = "Имя обязательно";
    }
    if (attrs.age && attrs.age < 0) {
      errors.age = "Возраст не может быть отрицательным";
    }
    if (!_.isEmpty(errors)) {
      return errors;
    }
  }
});
  • Метод validate возвращает объект ошибок или undefined.
  • Если метод возвращает значение, Backbone считает модель невалидной и не применяет изменения.
  • Событие invalid срабатывает при неудачной валидации, предоставляя возможность реагировать на ошибки.
var user = new User();
user.on("invalid", function(model, errors) {
  console.log(errors);
});
user.set({ age: -5 }, { validate: true });

Расширение возможностей через сторонние библиотеки

Для крупных приложений ручное написание всех правил валидации становится неудобным. На практике используются внешние библиотеки, интегрируемые с Backbone, которые упрощают управление правилами и ошибками.

Популярные библиотеки:

  1. Backbone.Validation Позволяет декларативно задавать правила валидации для атрибутов модели.

    _.extend(Backbone.Model.prototype, Backbone.Validation.mixin);
    
    var User = Backbone.Model.extend({
      validation: {
        name: {
          required: true,
          msg: "Имя обязательно"
        },
        email: {
          pattern: 'email',
          msg: "Неверный формат email"
        },
        age: {
          min: 0,
          msg: "Возраст не может быть отрицательным"
        }
      }
    });
    
    var user = new User();
    user.bind('validated:invalid', function(model, errors) {
      console.log(errors);
    });
    user.set({ email: "wrong" }, { validate: true });

    Основные преимущества:

    • Поддержка шаблонов ошибок для каждого атрибута.
    • Автоматическая привязка к представлениям (Views) для отображения ошибок.
    • Простая интеграция с формами через Backbone.View.
  2. Parsley.js (через адаптеры) Можно использовать для сложной клиентской валидации, включая асинхронные проверки. Подходит для форм с динамическими правилами, хотя требует интеграционного кода с Backbone.

  3. Validator.js Чисто функциональная библиотека для проверки значений, которую удобно использовать внутри метода validate. Пример интеграции:

    var User = Backbone.Model.extend({
      validate: function(attrs) {
        var errors = {};
        if (!validator.isEmail(attrs.email || "")) {
          errors.email = "Неверный формат email";
        }
        if (!_.isEmpty(errors)) return errors;
      }
    });

Асинхронная валидация

Backbone не поддерживает асинхронные проверки напрямую, но их можно реализовать через промисы или коллбеки.

Пример проверки уникальности email через сервер:

var User = Backbone.Model.extend({
  validate: function(attrs, options) {
    if (!attrs.email) return { email: "Email обязателен" };

    if (options.async) {
      return fetch('/api/check-email?email=' + encodeURIComponent(attrs.email))
        .then(response => response.json())
        .then(data => {
          if (!data.available) {
            this.trigger("invalid", this, { email: "Email уже занят" });
          }
        });
    }
  }
});

var user = new User();
user.set({ email: "test@example.com" }, { validate: true, async: true });

Интеграция с Backbone.View

Ошибки валидации можно автоматически отображать в представлениях:

var UserView = Backbone.View.extend({
  initialize: function() {
    this.listenTo(this.model, "validated:invalid", this.showErrors);
  },
  showErrors: function(model, errors) {
    for (var key in errors) {
      this.$('[name=' + key + ']').addClass('error').after('<span>' + errors[key] + '</span>');
    }
  }
});

Преимущество такого подхода — разделение логики модели и отображения ошибок, что повышает масштабируемость приложения.

Стратегии построения правил валидации

  1. Декларативные правила: удобно для большинства форм, где атрибуты и ошибки известны заранее.
  2. Программные проверки в validate: подходят для динамических или сложных зависимостей между атрибутами.
  3. Комбинированный подход: декларативные правила + отдельные программные проверки для нестандартных случаев.

Локализация сообщений об ошибках

Для многоязычных приложений рекомендуется хранить тексты ошибок в отдельных ресурсах:

var messages = {
  en: { required: "Required", email: "Invalid email" },
  ru: { required: "Обязательно", email: "Неверный формат email" }
};

var User = Backbone.Model.extend({
  validation: {
    name: { required: true, msg: messages.ru.required },
    email: { pattern: 'email', msg: messages.ru.email }
  }
});

Это упрощает поддержку и переключение языков в интерфейсе без изменения логики валидации.

Принципы эффективной валидации в Backbone

  • Выносить правила валидации в отдельный объект, а не смешивать их с логикой метода save.
  • Использовать события invalid и validated:valid для синхронизации с интерфейсом.
  • Минимизировать дублирование проверок, особенно для асинхронных правил.
  • Для сложных приложений рассматривать интеграцию специализированных библиотек (Backbone.Validation, Validator.js) вместо ручного кодирования всех проверок.

Эта архитектура позволяет создавать масштабируемые, надежные приложения на Backbone.js с централизованной и расширяемой системой валидации.