html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Работа с моделями данных в javascript из песочницы tutorial

Здравствуйте, Хабралюди.

Мал по-малу из моего опыта и наших проектов родилась небольшая библиотека для работы с моделями в джаваскрипте. Она так и называется — Model.js.

Я расскажу вам вкратце об этой библиотеке и этим постом запрашиваю обратную связь у тех, кто создавая сложные джаваскрипт-приложения, уже решает эту проблему каким-то определенным образом без фреймворков. Интересно также и мнение тех, кто только подыскивает подходящий инструмент для своих нужд: какой инструмент вам нужен и насколько вам подходит Model.js?

Зачем?


Чтобы упростить работу со слоем данных, не используя фреймворков. Текущая первая версия библиотеки — v0.1 весом около 12К — призвана помочь в первую очередь с валидацией данных и управлением событиями, в частности c событиями при изменении данных.

Что особенного?


Сахар. Обыкновенный приятный глазу синтаксический сахар.

Модель описыватся проще некуда.
var Note = new Model('Note', function () {
  this.attr('id!', 'number');
  this.attr('title', 'string', 'nonempty');
  this.attr('text', 'string');
});

Затем создаем сущности, как обычные объекты.
var note = new Note({ id: 123, title: "Hello World" });


Публичные свойства сущности


Геттеры значений атрибутов. В нашем примере это:
note.data.id
note.data.title
note.data.text

Сеттеры. Кроме изменения значений также «выстреливают» событие change.
note.data.id =
note.data.title =
note.data.text =
note.data = {…}

Геттер note.get(attrName[, attrName, …]) возвратит объект со значениями запрашиваемых атрибутов.

note.get() возвратит копию всех данных.

note.data() — то же самое, что и note.get().

Сеттеры note.set(attrName, value) и note.set({…}) не “выстреливают” событие change.

note.hasChanged говорит, изменены ли данные сущности с момента их последнего сохранения.

note.isNew говорит, сохранены ли данные сущности вообще хоть раз.

note.isPersisted говорит, сохранены ли последние изменения.

note.bind(eventName, handler) «вешает» обработчик. Кстати говоря, повесить обработчик любого события можно не только на отдельную сущность, но и на все сущности класса (Note.bind).

note.isValid говорит, валидны ли текущие данные модели.

note.errors собственно, возвращает ошибки данных, если они есть.

note.revert() откатывает несохраненные изменения и «выстреливает» событие revert.

Это все.

Вы спросите, где же методы сохранения и прочее-прочее? — Отвечу: использование библиотеки подразумевает, что разработчик должен реализовать эти методы самостоятельно как того требует логика его приложения.

Нужно отметить, что с сохранением есть один нюанс: если данные сохранились успешно, нужно об этом сообщить сущности при помощи приватного метода note._persist(), который также «выстреливает» событие persist.

Объяснение примером хорошо. Допустим, наше приложение работает в браузерном окружении и метод note.save() должен сохранить данные при помощи аджакса.

Note.prototype.save = function () {
  var note = this;
  return $.ajax({
    type: 'PUT',
    url: '/notes/'+note.data.id,
    data: note.data(),
    dataType: 'json'
  }).done(function (json) {
    note._persist();
  });
}

note.bind('persist', function () {
  $('h1', 'div#note'+this.data.id).html(this.data.title);
});

note.data = { id: 123, title: "abc", text: "" }
if (note.hasChanged && note.isValid) { // оппа Django-style
  note.save();
}


Проверка данных


При создании модели обязательно описывается каждый ее атрибут.
this.attr('title', 'string', 'nonempty')
Сперва указываем название атрибута, затем его валидаторы. Валидаторы, когда придет время, в объявленном порядке будут проверять значение атрибута.

Вообще, валидаторы — это обычные функции, которые принимают значения и возвращают ошибки, когда эти значения невалидны.
function validateMinLength(value, minLength) {
  if (value.length < minLength) return 'tooshort';
}

Если у вас есть необходимость использовать валидатор несколько раз — резонно его зарегистрировать, чтобы подключать по имени.
Model.registerValidator('array', function (value) {
  if (Object.prototype.toString.call(v) === '[object Array]') return 'wrongtype';
});
Model.registerValidator('minLength', validateMinLength);

Model.js имеет несколько базовых (уже зарегистрированных) валидаторов: number, string, boolean, nonnull, nonempty и in. Их, совсем как в нашем примере, можно подключать к атрибутам по названию.

Чтобы передать параметр валидатору при описании атрибута, нужно записать его, как в примере ниже, в виде массива:
this.attr('title', 'string', 'nonempty', [ 'minLength', 6 ]);

Валидаторы можно подключать и обычным дедовским методом, не регистрируя их.
this.attr('title', 'string', 'nonempty', [ 'minLength', 6 ], function (title) {
  if (title[0] !== title[0].toUpperCase()) return 'downcase';
});

Все это нужно, чтобы note.isValid мог сказать true или false, а note.errors мог вернуть объект с ошибками, если они есть.
note.data = { id: 'abc', title: '', text: 3 }; // полностью неверные данные
note.isValid // false
note.errors // { id: 'wrongtype', title: 'empty', text: 'wrongtype' }


События


Есть четыре события: initialize, change, persist и revert. Как говорилось выше, можно повесить обработчик на конкретную сущность (note.bind), а можно и на класс (Note.bind), так что обработчик станет общим для всех сущностей.

initialize «выстреливается» единожды при создании сущности: var note = new Note({…}). Так что вешать обработчик initialize имеет смысл только на класс.

change срабатывает каждый раз, когда меняется значение атрибута. Есть, правда, сеттеры, которые не дергают change (об этом было рассказано выше).

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

revert — когда логика приложения приказала откатить еще несохраненные изменения (при помощи метода note.revert()).

var ALLOWED_LANGUAGES = ['en', 'ua', 'ru'];
var Note = new Model('Note', function () {
  this.attr('id!', 'number');
  this.attr('title', 'string', 'nonempty');
  this.attr('lang', 'string', 'nonempty', [ 'in', ALLOWED_LANGUAGES]);
  this.attr('text', 'string');
});

Note.bind('initialize', function () {
  if (!this.data.lang) {
    this.set('lang', 'en'); // change не выстрелит — специальный такой сеттер!
  }
});

note.bind('change', function (changes) {
  if (changes.title) $('h1', 'div#note'+this.data.id).html(changes.title);
});


В завершение


Сейчас Model.js — это чистый state of the art, это промежуточный, но уверенно работающий результат. Если вы заинтересовались библиотекой, если у вас возникло желание попробовать ее применить, я буду рад ответить на ваши вопросы. Больше информации о том, как что работает можно найти в документации на гитхабе и в тестах.

Ну а пока пожелайте малютке доброго пути, ведь чтобы ей стать «взрослой» библиотекой, нужно проделать еще немало работы.
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

4

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • habrahabr.ru
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции