Новая стратегия создания комплексных виджетов: Почему 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 при разработке комплексных виджетов. Благодаря такому подходу, у новых виджетов хорошая структура, их удобно настраивать и кастомизировать.

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

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

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

Webix File Manager

Live demo >>

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

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

Webix DocManager

Live demo >>

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

Webix Query

Live demo >>

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

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

user manager

Live demo >>

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

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

Продвинутым пользователям 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 >>

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

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

Live demo >>

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

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

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

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

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

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

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

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

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

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

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

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

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

Live demo >>

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

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

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

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

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

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

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

Live demo >>

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

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

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

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

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

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

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

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

Что дальше

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

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