- Введение
- Наследование
- MK.Object
- MK.Array
В предыдущих статьях мы познакомились с общими принципами Матрешки: привязка элементов, события, наследование. В конце предыдущей статьи я задал себе вопрос: «Как разграничить состояние приложения (показать ли пользователю пароль) и данные приложения (логин, пароль, «запомнить меня»)».
Класс, который нам в этом поможет, называется MK.Object
, который наследуется от класса Matreshka
. Идея проста: у нас есть множество ключей, отвечающих за данные в экземпляре класса и мы считаем, что остальные свойства отвечают лишь за состояние приложения и не являются бизнес моделью.
._keys
, которое является объектом со значениями, которые нам безразличны. Массив бы нам не подошел, потому что, перед добавлением нового ключа надо было бы проверять, есть ли ключ в массиве, а при удалении, пришлось бы узнавать индекс, затем сдвигать следующие элементы. В случае объекта, мы получаем полноценное множество строк, для добавления нового ключа не нужно проверять его наличие, а для удаления требуется лишь вызов оператора delete
.
Для того, чтоб установить свойство, которое отвечает за данные, используется метод .jset
:
var mkObject = new MK.Object();
mkObject.jset( 'a', 1 );
console.log( mkObject.toJSON() ); // { a: 1 }
Документация к .jset: finom.github.io/matreshka/docs/Matreshka.Object.html#jset
Документация к .toJSON: finom.github.io/matreshka/docs/Matreshka.Object.html#toJSON
Теперь можем работать с новым свойством как обычно:
var mkObject = new MK.Object();
mkObject.jset( 'a', 1 );
mkObject.a = 2;
console.log( mkObject.toJSON() ); // { a: 2 }
В том числе, мы можем использовать унаследованные от класса Matreshka
методы:
mkObject.bindElement( 'a', '.my-element' );
mkObject.on( 'change:a', handler );
Если мы установим свойство, не добавив его ключ в множество ключей, в результате работы метода .toJSON
мы не увидим этого свойства:
var mkObject = new MK.Object();
mkObject.jset( 'a', 1 );
mkObject.b = 3;
console.log( mkObject.toJSON() ); // { a: 1 }
Можно добавить ключи в список ключей, используя метод .addJSONKeys
Дока: finom.github.io/matreshka/docs/Matreshka.Object.html#addJSONKeys
mkObject.addJSONKeys( 'b', 'c' );
Здесь следует важное правило: если вы не уверены наверняка, какие свойства должны попадать в результат работы функции .toJSON
, всегда используйте .jset
вместо обычного присваивания. Если ключи известны, то, лично я, предпочитаю всегда задавать данные по умолчанию:
var MyClass = Class({
'extends': MK.Object,
constructor: function( data ) {
this
.initMK()
.jset({ // данные по умолчанию
a: 1,
b: 2,
c: 3
})
.set( data ) // кастомные данные (data - обычный объект с данными)
;
}
});
Обратите внимание на вызов .initMK
. Здесь он инициализирует не только объекты событий и «специальных» свойств, но и объект-множество ключей. Кроме этого, он добавляет необходимые обработчики событий вызывая событие "modify"
при изменении данных. Пример:
var mkObject = new MK.Object();
mkObject.jset({
a: 1,
b: 2
});
mkObject.c = 3;
mkObject.on( 'modify', function() {
alert( 'Data is changed' );
});
mkObject.a = 4; // вызывает обработчик
mkObject.b = 5; // вызывает обработчик
mkObject.c = 6; // обработчик не вызывается, так как ключ "c" не обозначен, как данные
Если передать классу аргумент в виде объекта, он интерпретирует его, как данные:
var mkObject = new MK.Object({ a: 1, b: 2 });
// то же самое, что и
var mkObject = new MK.Object();
mkObject.jset({ a: 1, b: 2 });
Перебрать данные можно с помощью метода .each
:
var mkObject = new MK.Object();
mkObject.jset({
a: 1,
b: 2
});
mkObject.c = 3;
mkObject.each( function( item, key ) {
console.log( key );
}); // выведет 'a', 'b'
Дока: finom.github.io/matreshka/docs/Matreshka.Object.html#each
Проверить, есть ли в объекте какое-нибудь свойство можно с помощью метода .hasOwnProperty
var mkObject = new MK.Object();
mkObject.jset( 'a', 1 );
mkObject.b = 2;
alert( mkObject.hasOwnProperty( 'a' ) ); // true
alert( mkObject.hasOwnProperty( 'b' ) ); // false ('b' не является данными)
Это позволяет юзать конструкцию for..in
, как для обычного объекта:
for( var i in mk ) if( mk.hasOwnProperty( i ) ) {
doSomething(i, mk[i])
}
Есть еще ряд методов, имена которых говорят сами за себя:
.keyOf
, который ищет ключ по значению и возвращает ключ (аналог .indexOf
для массива).
.keys
, возвращающий массив ключей.
.removeJSONKeys
, удаляющий ключи из множества ключей, отвечающих за данные.
Взгляните на измененный пример из предыдущей статьи: jsbin.com/ATAPUCo/6/
В конструкторе мы задаём данные по умолчанию:
...
constructor: function () {
this
.initMK()
.jset({ // вот здесь
userName: '',
password: '',
rememberMe: true
})
.bindings()
.events();
},
...
А затем, вместо того, чтоб вручную конструировать объект, который должен быть послан на сервер, мы вызываем метод .toJSON
:
...
login: function () {
if (this.isValid) {
alert( JSON.stringify( this.toJSON() ) );
}
return this;
}
...
В завершение
Теперь мы знаем, как отделить данные Матрешки от состояний, которые не интересны бекенду. Замечательно. Но что, если нам нужно множество данных? Что-то типа массива или коллекции из Backbone.js. Решение — класс MK.Array
, о котором я расскажу в следующей статье.
Спасибо, что прочли статью до конца. Всем добра и хорошего кодинга.
Автор: Finom