Новая стратегия создания комплексных виджетов: Почему Webix Jet?

В этом году мы разработали новую концепцию создания комплексных виджетов и
реализовали её на нескольких примерах: File Manager, Document Manager, Query и
User Manager. Каждый из этих комплексных виджетов написан как Webix Jet
приложение, что делает их гибкими, настраиваемыми и многофункциональными.
Исходный код такого приложения не очень прост в освоении, но как только вы
поймёте общую идею, перед вами откроется широкий спектр возможностей.

Life after File Manager 7.2: The benefits of Jet-based widgets

Давайте познакомимся с основными возможностями новых виджетов и узнаем
преимущества Jet-подхода.

Почему это важно

По своей сути, комплексные виджеты Webix — это небольшие приложения. Они
достаточно хорошо справляются со своими основными задачами, но настроить их
под свои нужды не так-то просто. Всё дело в публичном API, у которого есть
некоторые ограничения. Тем не менее гибкость в настройках необходима.

Именно поэтому мы решили использовать
Webix Jet</a >
при разработке комплексных виджетов. Благодаря такому подходу, у новых
виджетов хорошая структура, их удобно настраивать и кастомизировать.

Что нового для конечных пользователей

Прежде всего, мы не просто переписали код, но добавили множество новых фич.
Например, в новом File Manager 7.2 можно:

  • Переключаться между тремя режимами интерфейса: list, cards и double view
  • Предварительно просматривать файлы
  • Редактировать текстовые файлы
  • Добавлять файлы и папки
  • Скачивать и загружать файлы
  • Работать с файлами на устройствах с маленьким экраном

Webix File Manager

Live demo >></a >

Document Manager предлагает еще больше функций:

  • Корзина для хранения удалённых файлов и папок;
  • Добавление файлов в избранное;
  • Возможность делиться файлами с другими пользователями;
  • Просмотр недавних файлов;
  • Добавление тегов файлам;
  • Поиск по имени или тегу;
  • Возможность комментировать файлы;
  • Просмотр и редактирование Excel файлов.

Webix DocManager

Live demo >></a >

Query может похвастаться удобным и интуитивно понятным интерфейсом для
фильтрации данных.

Webix Query

Live demo >></a >

Кстати, вы уже
слышали о User manager</a >? Это новый виджет для управления правами доступа. В нем можно:

  • управлять правами пользователей
  • группировать права в роли
  • отслеживать операции по управлению уровнями доступа

user manager

Live demo >></a >

Это то, что получат конечные пользователи виджетов «из коробки». Если
какой-либо функционал выходит за пределы базового, то вы, разработчики, можете
запросто добавить его в приложение.

Что нового для разработчиков

Продвинутым пользователям Webix Jet-виджеты покажутся несколько
нестандартными. Эти виджеты разработаны иначе и требуют другого подхода от
разработчика. Несмотря на то, что у каждого виджета свои особенности, всех их
объединяют следующие черты:

  • Webix Jet структура и ООП
  • Реактивные свойства вместо привычных настроек и событий
  • Настраиваемые view-классы и сервисы вместо классического Webix API
  • Переопределение как средство кастомизации

Webix Jet и изменения в интерфейсе

Webix Jet позволяет эффективно организовать код и архитектуру комплексных
виджетов. Это значит:

  • части интерфейса хранятся в отдельных модулях (views)
  • логика приложения также хранится в специальных модулях (services)
  • у исходного кода нет приватных областей, поэтому любую его часть можно
    использовать и изменять

Благодаря классическому ООП, у вас есть возможность:

  • расширять view-классы и сервисы
  • переопределять текущий функционал или добавлять новый
  • добавлять новые компоненты

Например, чтобы изменить UI, найдите необходимый view-класс и переопределите
его метод config() так, чтобы он возвращал нужную вам
конфигурацию Webix. Давайте добавим новую опцию в меню виджета Query:

class ActionsPopupView extends query.views.actions {
config() {
const ui = super.config();
const list = ui.body;
list.data.push({ id: "custom", value: "Custom option" });
list.yCount = 5;
return ui;
}
}

Live demo >></a >

Чтобы изменить какой-либо функционал компонента, нужно переопределить
методы view-класса (например, init()). Давайте добавим
действие по клику на новую опцию опцию, задав обработчик
события:

class ActionsPopupView extends query.views.actions {
config() {
...
}
init(){
super.init();
this.on(this.app, "action", (id, item) =&gt; {
if (id === "log")
this.LogFilter(item);
});
}
LogFilter(item){
console.log(`Filter ID: ${item}`);
}
}

Live demo >></a >

Реактивное состояние: Как изменять свойства и следить за изменениями

Помимо обычных настроек типа width, url и
др., у Jet-виджетов есть реактивные
свойства</a >. Они были придуманы для
обеспечения коммуникации между частями приложения. Реактивные
свойства могут отражать значение любого параметра или сигнализировать о его
изменении обработчикам событий.

В отличие от событий и свойств, реактивное состояние:

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

Вы можете задавать реактивные свойства в объекте конфигурации виджета:

// по умолчанию будет отображаться папка с недавно просмотренными файлами
view:"docmanager", id:"dm", source:"recent"

Реактивное состояние виджета доступно через метод getState():

const state = $$("dm").getState();

После этого вы можете:

  • подписаться на изменения этого параметра и выполнять какие-либо действия,
    если они произошли
{
view: "docmanager",
url: "https://docs.webix.com/docmanager-backend/",
on: {
onInit: app =&gt; {
const state = app.getState();
state.$observe("source", (v,o) =&gt; { /* ваш код */ });
},
}
}
  • изменять параметры, и виджет будет реагировать на эти изменения
$$("dm").getState().source = "trash";

Вы можете изменить сразу несколько реактивных свойств:

const state = $$("docManager").getState();
state.$batch({
source: "files",
path: "/Music",
mode: "cards"
});

Вам не нужно обновлять виджет после изменений. Обработчики сделают это
самостоятельно.

Live demo >></a >

Переопределение и сервисы: Кастомизация логики виджетов

У Jet-виджетов нет привычного публичного API, поэтому вы не сможете настроить их
по старинке. Вместо этого у виджетов есть сервисы, которые
хранят их внутреннюю логику. Например, если вам нужно по-другому реализовать
коммуникацию между сервером и клиентом, вы можете переопределить сервис
Backend.

Любой метод можно вызвать напрямую:

// получить все папки и файлы
$$("filemanager").getService("backend").files("/").then(files =&gt; { ... });

…и любой метод можно переопределить. Например, вы можете изменить метод
files(), чтобы загружать содержимое директорий по-другому:

class MyBackend extends fileManager.services.Backend {
// вы можете обращаться к серверу
files(id) {
return webix.ajax("//docs.webix.com/filemanager-backend/files", { id })
.then((data) =&gt; data.json());
}

// … другие методы
}

webix.ui({
view: «filemanager»,
url: «https://docs.webix.com/filemanager-backend/»,
override: new Map([[fileManager.services.Backend, MyBackend]]),
});

Live demo >></a >

Общие советы по настройке виджетов

чтобы понять, что именно вы хотите изменить, читайте исходный код. Есть
несколько базовых принципов настройки:

  • изменения в UI: найдите view-class компонента (вы также можете
    обратиться к карте классов в
    соответствующем разделе документации</a >) и переопределите в нём метод config():
    пример</a >
  • изменения логики компонента: найдите view-class компонента и
    переопределите метод init()или другие методы класса:
    пример</a >
  • изменения или добавление функциональности: добавьте новые или
    переопределите уже существующие методы view-классов и сервисов; например,
    вам нужен сервис Operations, если вы хотите обрабатывать
    операции в приложении по-другому:
    пример</a >
  • адаптация виджета к вашему бэкенду: найдите сервис Backend или
    другие бэкенд-сервисы (например, Tags или Users), а также их эквиваленты для работы с локальными данными (LocalData, LocalUsers, LocalTags) и переопределите их методы:
    пример</a >

У Jet-виджетов нет приватного АПИ. Вы можете вызывать и переопределять любые
методы, а также изменять любые свойства и компоненты. Это удобно, но в то же время предполагает вашу ответственность за свой код.

С гибкостью приходит ответственность

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

С великой гибкостью приходит великая ответственность … и любовь к чтению исходного кода. Так как не
существует привычного API, мы не документировали каждый метод каждого компонента
или сервиса — за исключением Backend сервиса, который вам нужно будет кастомизировать чаще всего 🙂 Мы также предлагаем гайды и практические
руководства по общим задачам.

Если документация кажется вам недостаточной, пишите, и мы ее дополним. Однако для того, чтобы на самом деле понять как
устроены Jet-виджеты, что такое «views», сервисы и многое другое, вам
необходимо читать исходный код. Если вы испытываете какие-либо затруднения,
обращайтесь в нашу службу поддержки. Мы всегда рады помочь!

Что дальше

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

Следите за обновлениями и будьте здоровы 🙂