Как стать автором
Обновить

Комментарии 34

Видимо авторам статей о фреймворках лучше самим добавлять эту картинку :).
А вам ещё и приписывать про гипотетический метод toMatreshka (или просто to).
не надо было брать название которое прочно ассоциируется с другим опен-сурс проектом
Тот — Matroska, а тут есть balalaika (DOM) уже. Осталось Event driven движок сделать (vodka, ushanka?).
Ещё пара фреймворков и следующий можно называть Boyan
Вам бы примеров побольше, например
— простенькое дерево категорий (на генерацию хтмля)
— взаимодействие со сторонними библиотеками (например с картами, добавляем десяток точек они появляются на карте, связываем клик по маркеру и содержимое попапа с моделью)
— работа с hash частью url'a и историей (я понимаю что это немного за рамками библиотеки, но всеже)
Спасибо, записал в список.
Давно присматривался и уже забыл, а тут ваша статья.

Ни капли злой иронии, но почему я должен посмотреть Matreshka.js если мне безумно крутым и легким показался Mithril.js?

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

Теперь классы — а почему бы не ES6 синтаксис сразу в документации, прям жирным шрифтом? IE8 идет лесом как мне кажется, уже давно и навсегда.

А вообще побольше примеров и, желательно, посложнее и более приближенных к реальным задачам (например гриды, формы и так далее).
но почему я должен посмотреть Matreshka.js если мне безумно крутым и легким показался Mithril.js?

Все фреймворки хороши по-своему. Вы мне ничего не должны :)

Теперь классы — а почему бы не ES6 синтаксис сразу в документации, прям жирным шрифтом?

Когда ES6 будет использоваться повсеместно, так и сделаем. Сейчас нет в этом смысла. Многие даже не в курсе, что это такое.

IE8 идет лесом как мне кажется, уже давно и навсегда.

К сожалению, это не так. Еще как минимум год разработчикам прийдется мучиться. Посмотрите любую статистику.

А вообще побольше примеров и, желательно, посложнее и более приближенных к реальным задачам (например гриды, формы и так далее).

Полностью согласен. Но очень сложно соблюсти баланс между максимальной понятностью и функционалом примера.

Но вы же хотите привлечь внимание, назовите причины по которым это стоит сделать с оглядкой на упомянутый крутой фрэймворк.
Неужели вам не хочется понять в сравнении преимущества своего детища? Я же не издеваюсь ни капли.

Да уж я с вами не соглашусь, про ES6 знают и его хотят использовать. Многие ждали и верили, дождались и используют.

Я уже год назад отказался от поддержки IE < 8 и не собираюсь возвращаться и извращаться. Того же и всем желаю.

Так для новичков будут простые примеры, а из реальной жизни — для тех кто поигрался и захотел на продакшне.
Но вы же хотите привлечь внимание, назовите причины по которым это стоит сделать с оглядкой на упомянутый крутой фрэймворк.
Неужели вам не хочется понять в сравнении преимущества своего детища? Я же не издеваюсь ни капли.

Я вряд ли когда-то буду говорить, что такой-то фреймворк плохой, а этот лучше всех. Почему стоит использовать или не использовать Матрешку, решаете вы сами. Главная задача разработчика любого свободного инструмента — дать возможность определиться, нужно ли его использовать или нет. Мне кажется, здесь с этим всё в порядке: есть сайт, есть «рекламирующие» тексты, есть документация, есть примеры (в том числе и средних размеров: TodoMVC).

Я уже год назад отказался от поддержки IE < 8 и не собираюсь возвращаться и извращаться.

Я и не против, но клиенты требуют.
Зачем же вы добавляете в ваше решение излишний (на мой взгляд) функционал? Нет желания пользоваться AngularJS только от того, что мне не нужны их фильтры да сервисы, а вот связывание хочется.

Думаю перейти на «матрешку», но можно ли уменьшить ее вес, выпилив все, кроме связывания?
Связывание тут реализуется достаточно просто. Любой программист со средним опытом может реализовать standalone функцию bindNode с помощью Object.defineProperty и addEventListener.
Решил для небольшой тренеровки после обеда написать отдельную функцию bindNode.

Вот, если вам интересно:
window.bindNode = function bindNode( object, key, node, binder ) {
	var value = object[ key ];
	Object.defineProperty( object, key, {
		get: function() {
			return value;
		},
		set: function( v ) {
			binder.setValue.call( node, v );
		}
	});
	
	node.addEventListener( binder.on, function() {
		value = binder.getValue.call( node );
	});
};


Функция поддерживает только один набор аргументов, аргумент node должен быть DOM нодой, нет стандартных байндеров и пр., но вы можете сами дописать, это не трудно.

jsbin.com/mabetap/2/edit?html,js,console,output
Введите data.x = 'Hello world' в консоли.
Ну и «многие ко многим» не поддерживаются. Но это всё детали.
Спасибо. Возможно было бы очень удобно, если бы вы разделили фреймворк на части, чтобы можно было наращивать функционал постепенно, по мере надобности.

Использую ваш фреймворк в связке с React. Думаю об использовании балалайки )
Возможно было бы очень удобно, если бы вы разделили фреймворк на части, чтобы можно было наращивать функционал постепенно, по мере надобности.

Тогда фреймворк уеньшится на 20%, по моим оценкам, что очень немного, при этом не отразившись на производительности. Поэтому, я не вижу в этом смысла.

Использую ваш фреймворк в связке с React

Буду благодарен, если поделитесь опытом (здесь или в личке). Очень интересно.

Буду благодарен, если поделитесь опытом (здесь или в личке). Очень интересно.


Постараюсь что нибудь написать специально для вас (распространять имеющиеся исходники не имею права)
Идея в том, чтобы позволить программисту рендерить структуру виджета с помощью React, но обновлять конкретные значения виджета через связывание.
Пример использования
define('components/Timer', ['react', 'matreshka'], function (React, Matreshka) {
    return React.createClass({
        displayName: 'Timer',

        // Увеличиваем значение таймера используя модель
        tick: function () {
            this.model.value = Number(this.model.value) + 1;
        },

        // Обнуляем таймер используя модель
        clean: function(){
            this.model.value = 0;
        },

        // Создаем модель с использованием Matreshka
        initModel: function(){
            this.model = new (Matreshka.Class({
                'extends': Matreshka.Object,
                constructor: function (node, value) {
                    this.value = value;

                    this.bindNode('value', node, {
                        setValue: function (v) {
                            this.innerHTML = v;
                        }
                    });
                }
            }))(this.getDOMNode().lastChild, this.props.value);
        },

        // Вешаем обработчики на виджет
        componentDidMount: function () {
            this.initModel();

            this.timer = setInterval(this.tick, 500);

            this.getDOMNode().lastChild.addEventListener('click', this.clean);
        },

        // Удаляем обработчики с виджета
        componentDidUnmount: function () {
            clearInterval(this.timer);

            this.getDOMNode().lastChild.removeEventListener('click', this.clean);
        },

        // рендерим виджет
        render: function () {
            return React.createElement('div', null, [
                React.createElement('span', null, 'Timer: '),
                React.createElement('span', {title: 'Click to reset'})
            ]);
        }
    });
});

Более сложный пример. Головной элемент состоит из подэлемента, который способен изменять свою HTML структуру (благодаря React). Тот, в свою очередь, состоит из еще более мелких элементов, которые могут изменять свое значение (благодаря Matreshka).

Пример использования
var todo = React.createClass({
        inc: function(){
            this.model.value = Number(this.model.value) + 1;
        },

        componentDidMount: function(){
            this.model = new (Matreshka.Class({
                'extends': Matreshka.Object,
                constructor: function (node, value) {
                    this.value = value;

                    this.bindNode('value', node, {
                        setValue: function (v) {
                            this.innerHTML = v;
                        }
                    });
                }
            }))(React.findDOMNode(this.refs.data), this.props.value);

            React.findDOMNode(this.refs.button).addEventListener('click', this.inc);
        },

        render: function(){
            return React.createElement('li', null, [
                React.createElement('span', {ref: 'data'}, this.props.value),
                React.createElement('input', {type: 'button', value: 'inc', ref: 'button'})
            ]);
        }
    });

    var todoList = React.createClass({
        getInitialState: function(){
          return {items: this.props.items};
        },

        addLi: function(text){
            var newState = this.state.items;
            newState.push(React.createElement(todo, {value: text}));
            this.setState(newState);
        },

        render: function(){
            return React.createElement('ul', null, this.state.items)
        }
    });

    var todoApp = React.createClass({
        addTodo: function(){
            this.refs.todoList.addLi(React.findDOMNode(this.refs.text).value);
            React.findDOMNode(this.refs.text).value = '';
        },

        componentDidMount: function(){
            React.findDOMNode(this.refs.button).addEventListener('click', this.addTodo);
        },

        componentDidUnmount: function(){},

        render: function(){
            return React.createElement('div', null, [
                React.createElement(todoList, {ref: 'todoList', items: []}),
                React.createElement('input', {type: 'text', ref: 'text'}),
                React.createElement('input', {type: 'button', value: 'Add', ref: 'button'})
            ]);
        }
    });

Круто, спасибо. Небольшое замечание по Матрешке: если вам нужно свойство с определенным типом, юзайте mediate.

this.mediate('value', Number);

Тогда вместо

this.model.value = Number(this.model.value) + 1;

Можно писать

this.model.value++;
Создание сервера сборки, к сожалению, штука очень трудозатратная. Если еще интересуетесь фреймворком, я могу предложить вот эту штуку. Вся функциональность, отвеающая за классы там отсутствует (хотя, много лишнего может быть для вас).
Где-то видел сравнение производительности матрешки и прочих популярных фреймворков.
Подскажите, где посмотреть?
Как раз решил обкатать матреху, до сих пор пользовался только jquery, да все велосипеды изобретал )))
Самый крутой ember, получается… даже не слышал.
Ладно, опробую матреху чисто из-за названия.
Как подметили в комментариях ниже, эти тесты не совсем корректны, и Ангуляр, при определенных условиях, может работать быстрее всех (хотя не могу судить).
Хорошо бы поиск нормальный по документации сделать.
Вот я новичек, не знаю и не помню методов матрешки, а хочу найти «взаимодействие с DOM», например.
Гуглить не получается, тк сайт на скриптах и индексируется плохо.
Это проблема… Подумаю, как решить.
И спасибо за статью.
Готовлю еще)
Ок. Дайте знать, а то не всегда успеваю читать Хабру.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий