НОВОСТИ Объектно-ориентированная альтернатива jquery

Alvaros
Онлайн
Регистрация
14.05.16
Сообщения
21.452
Реакции
101
Репутация
204
Много кто использует jquery в своих проектах, в связи с простотой и легкостью, с которой его можно подключить на страницу, несмотря на то что существует достаточное количество объектно ориентированных фреймворков с компонентным подходом. Однако почти все они создают html разметку из javascript кода, что не всегда удобно, для совместного их использования с другими библиотеками, также создание разметки на js занимает какое-то время на стороне клиента, либо приходится делать серверный рендеринг на node.js что исключает их использование с другими языками например php.

Получается нужно постоянно выбирать, сравнивать все плюсы и минусы, или учить несколько фреймворков для разных проектов, для одного jquery, второго angular, а для будущего присматриваться к vue.js.

Было-бы здорово иметь один инструмент который может справиться со всеми требуемыми задачами, а именно:

  1. Встраиваться в уже отданную сервером страницу, без необходимости серверного рендеринга на node.js и возможность использования его с любыми другими библиотеками
  2. Иметь объектно-ориентированный, компонентный подход построения приложения, четкую и понятную структуру, возможность наследования свойств.
  3. Легкость в изучении, небольшой размер, производительность, возможность применять его как в маленьких так и больших проектах, а также для создания виджетов, слайдеров и т.д.


Как вы наверное уже догадались, здесь я как раз и хочу его представить —


Фреймворк встраивается в уже отданную сервером страницу с помощью data- свойств.
Таким образом нам не нужно создавать шаблоны на каком либо другом языке в js коде, мы просто используем уже готовый html.

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

Уже готовый, похожий пример можно покликать

После ввода имени пользователя в форму, приложение отобразит его имя в приветствии, кнопке выхода, отобразит сообщение о новом посетителе и создаст новый контейнер в массиве с пользователями, а также сохранит данные в localStorage. После перезагрузки страницы, возьмет имя из localStorage. При клике по кнопке «выйти из профиля» удалит данные со всех компонентов и переменную из localStorage и отобразит сообщение о выходе посетителя.

Давайте создадим четыре компонента: форму входа — form, приветствие — greeting, кнопку выхода — logout и массив со всеми посетителями — users_array.

Создадим html разметку всех компонентов:








Введите имя



Submit









Привет: guest




























пользователь - user_name_1









пользователь - user_name_2














В коде выше мы создали четыре компонента: три из них с типом «container» и один с типом «array» — массив со всеми посетителями. Контейнер — это компонент, в котором сгрупированы, какие либо html свойства, например текст, атрибут, слушатель события и т.д. Все свойства имеют определенный тип. Массив это компонент для работы с однотипными контейнерами, у массива так-же как и у контейнера могут быть различные свойства.

В примере выше мы указали свойства в html разметке с помощью data- атрибутов, также свойства можно указать из javascript кода, чтобы не писать их в разметке.

Теперь перенесем их в javascript:


var StateMap = {

form: {//форма входа
container: "form",
props: ["input", "click"],
methods: {

click: function(){
event.preventDefault(); //отменяем перезагрузку страницы

//this - указывает на свойство, в обработчике события которого мы находимся, parent - доступ к контейнеру из свойства
//получаем данные свойства input
var text = this.parent.props.input.getProp();
console.log(text);
}
},
},
greeting: {//приветствие

container: "greeting",
props: [ "user_name", ],
methods: {
}
},
logout: { //кнопка выхода

container: "logout",
props: [ "user_name", ],
methods: {
},
},
users_array: { //массив с пользователями
selector: "div.row", //уточняющий селектор
arrayProps: [ "message"], //свойство массива

container: "user", //контейнер массива
props: [ "user_name", ], //свойство контейнера
methods: {
},
},
}
window.onload = function(){//создаем экземпляр приложения htmlix

var HM = new HTMLixState(StateMap);
console.log(HM);
}



В примере выше мы перенесли компоненты в javascript код. В компоненте form свойстве click мы записываем данные введенные пользователем в переменную text и выводим их пока-что в консоль. Далее эти данные мы будем использовать во всех оставшихся компонентах. Для того чтобы компоненты узнали о том что данные обновились мы будем использовать пользовательские события.

Добавим событие «emiter-set-name»:


eventEmiters: { //добавляем объект со всеми пользовательскими событиями в описание приложения

["emiter-set-name"]: {prop: ""}, //событие с начальными данными

},


///вызываем событие в свойстве click компонента form и передаем в него полученные данные
click: function(){
event.preventDefault();
var text = this.parent.props.input.getProp();
this.rootLink.eventProps["emiter-set-name"].setEventProp(text);

//сохраняем имя пользователя в localStorage
window.localStorage.setItem('user_name', name);
}


//слушаем событие во всех остальных компонентах и обновляем их свойства
greeting: {
container: "greeting",
props: [ "user_name", ['listen_set_name', "emiter-set-name", "" ],], //создали свойство слушатель события в компоненте
methods: {

listen_set_name: function(){
//получили данные из события и обновили свойство user_name
this.parent.props.user_name.setProp( this.emiter.getEventProp() );
}
},
},


logout: {

container: "logout",
props: [ "user_name", ['listen_set_name', "emiter-set-name", "" ] ],
methods: {

listen_set_name: function(){//слушаем событие и обновляем свойство user_name

this.parent.props.user_name.setProp( this.emiter.getEventProp() );
},
},
},



users_array: {
selector: "div.row",
arrayProps: [ "message", ['listen_set_name', "emiter-set-name", ""], ],
arrayMethods: {

listen_set_name: function(){//слушаем событие в свойстве массива и создаем новый контейнер с полученными данными

this.parent.add( {user_name: this.emiter.getEventProp()} );

//выводим сообщение о новом посетителе
this.parent.props.message.setProp("новый посетитель - "+this.emiter.getEventProp());

},
container: "user",
props: [ "user_name", ],
methods: {
},
},



window.onload = function(){

var HM = new HTMLixState(StateMap);

//проверяем есть ли переменная user_name в localStorage и при ее наличии вызываем событие
var name = window.localStorage.getItem('user_name');
if(name != null)HM.eventProps["emiter-set-name"].setEventProp(name);

console.log(HM);

}




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

Теперь создадим событие «emiter-exit-user» для выхода пользователя:


eventEmiters: {
/* ... */
["emiter-exit-user"]: {prop: ""},

}


//вызываем событие в компоненте logout и передаем в него имя пользователя
logout: {
container: "logout",
props: [ /* ... */, ["exit", "click", "a:first-of-type"],], //создали новое свойство - слушатель события "click" и указали его вторым способом с помощью массива

methods: {
/* ... */
exit: function(){
//получаем имя пользователя
var user_name = this.parent.props.user_name;

//вызываем событие
this.rootLink.eventProps["emiter-exit-user"].setEventProp( user_name.getProp() );

//удаляем пользователя из localStorage
window.localStorage.removeItem('user_name');

//очищаем свойство компонента
user_name.setProp("");
}
},
},


users_array: {
selector: "div.row",
arrayProps: [ /* .. */, ['listen_exit_user', "emiter-exit-user", ""], ], //добавили свойство - слушатель события "emiter-exit-user"

arrayMethods: {
/* ... */
listen_exit_user: function(){
//data - доступ ко всем контейнерам из массива
this.parent.data.forEach(container=>{

if(container.props.user_name.getProp() == this.emiter.getEventProp()){

container.remove(true); //удалили контейнер
}
});

//добавили сообщение
this.parent.props.message.setProp( this.emiter.getEventProp()+" - покинул сайт");
},
},
container: "user",
props: [ "user_name", ],
methods: {
},
},


greeting: {

container: "greeting",
props: [/* ... */, ['listen_exit_user', "emiter-exit-user", ""] ],
methods: {

listen_exit_user: function(){
//удалили имя пользователя из свойства
this.parent.props.user_name.setProp("");
}
},
},




Это был краткий обзор основных принципов построения приложения на htmlix, полный код данного примера, вместе с использованием вспомогательных методов можно посмотреть
 
Сверху Снизу