3.5.17.2. Универсальный JavaScriptComponent

JavaScriptComponent - это простой компонент пользовательского интерфейса, который представляет собой универсальную обёртку для использования любой готовой библиотеки JavaScript в приложении на базе CUBA напрямую, без необходимости подключать компонент Vaadin.

Компонент можно использовать в XML-дескрипторе экрана, декларативно настраивать динамические свойства и зависимости JavaScript.

XML-имя компонента: jsComponent.

Определение зависимостей

Вы можете задать для компонента несколько зависимостей (js и css). Каждая зависимость должна соответствовать одному из следующих источников:

  • Ресурс WebJar - начинается с webjar://

  • Файл, расположенный в локальном каталоге VAADIN - начинается с vaadin://

Пример добавления зависимостей:

jsComponent.addDependencies(
        "webjar://leaflet.js",
        "http://code.jquery.com/jquery-3.4.1.min.js"
);
jsComponent.addDependency(
        "http://api.map.baidu.com/getscript?v=2.0", DependencyType.JAVASCRIPT
);
Функция инициализации

Для компонента необходимо задать функцию инициализации. Имя этой функции будет использовано JavaScript-коннектором для поиска точки входа (подробнее о коннекторах см. ниже).

В пределах окна имя функции инициализации должно быть уникальным.

Имя функции можно передать в компонент с помощью метода setInitFunctionName():

jsComponent.setInitFunctionName("com_company_demo_web_screens_Sandbox");
Определение JavaScript-коннектора

Чтобы использовать компонент JavaScriptComponent для подключения библиотеки JavaScript, вам необходимо создать JavaScript-коннектор - функцию, которая будет инициализировать компонент JavaScript и управлять коммуникацией между сервером и кодом JavaScript.

Из функции коннектора доступны следующие методы:

  • this.getElement() возвращает HTML DOM элемент компонента.

  • this.getState() возвращает распределенный объект состояния с текущим состоянием компонента как синхронизируемый объект с серверной стороны.

Возможности компонента

Ниже перечислены возможности компонента JavaScriptComponent, которые позволяют следующее:

  • Задать объект состояния, который можно использовать в коннекторе на стороне клиента и который будет доступен в поле data состояния компонента, к примеру:

    MyState state = new MyState();
    state.minValue = 0;
    state.maxValue = 100;
    jsComponent.setState(state);
  • Зарегистрировать функцию, которая может быть вызвана из кода JavaScript по указанному имени, например:

    jsComponent.addFunction("valueChanged", callbackEvent -> {
        JsonArray arguments = callbackEvent.getArguments();
    
        notifications.create()
                .withCaption(StringUtils.join(arguments, ", "))
                .show();
    });
    this.valueChanged(values);
  • Вызвать именованную функцию, которую JavaScript-коннектор добавил к объекту-обёртке коннектора.

    jsComponent.callFunction("showNotification ");
    this.showNotification = function () {
            alert("TEST");
    };
Пример использования JavaScriptComponent

В этом разделе описан пример интеграции сторонней JavaScript-библиотеки в приложение CUBA. В качестве примера мы взяли библиотеку Quill Rich Text Editor, доступную по адресу https://quilljs.com/. Чтобы использовать Quill в своём проекте, необходимо выполнить шаги, описанные ниже.

  1. Добавьте следующую зависимость к модулю web:

    compile('org.webjars.npm:quill:1.3.6')
  2. Создайте файл quill-connector.js в каталоге проекта web/VAADIN/quill в модуле web.

  3. Добавьте в этот файл код реализации коннектора:

    com_company_demo_web_screens_Sandbox = function () {
        var connector = this;
        var element = connector.getElement();
        element.innerHTML = "<div id=\"editor\">" +
            "<p>Hello World!</p>" +
            "<p>Some initial <strong>bold</strong> text</p>" +
            "<p><br></p>" +
            "</div>";
    
        connector.onStateChange = function () {
            var state = connector.getState();
            var data = state.data;
    
            var quill = new Quill('#editor', data.options);
    
            // Subscribe on textChange event
            quill.on('text-change', function (delta, oldDelta, source) {
                if (source === 'user') {
                    connector.valueChanged(quill.getText(), quill.getContents());
                }
            });
        }
    };
  4. Создайте экран с описанием компонента jsComponent:

    <jsComponent id="quill"
                 initFunctionName="com_company_demo_web_screens_Sandbox"
                 height="200px"
                 width="400">
        <dependencies>
            <dependency path="webjar://quill:dist/quill.js"/>
            <dependency path="webjar://quill:dist/quill.snow.css"/>
            <dependency path="vaadin://quill/quill-connector.js"/>
        </dependencies>
    </jsComponent>
  5. Контроллер этого экрана включает в себя следующую реализацию:

    @UiController("demo_Sandbox")
    @UiDescriptor("sandbox.xml")
    public class Sandbox extends Screen {
        @Inject
        private JavaScriptComponent quill;
    
        @Inject
        private Notifications notifications;
    
        @Subscribe
        protected void onInit(InitEvent event) {
            QuillState state = new QuillState();
            state.options = ParamsMap.of("theme", "snow",
                    "placeholder", "Compose an epic...");
    
            quill.setState(state);
    
            quill.addFunction("valueChanged", javaScriptCallbackEvent -> {
                String value = javaScriptCallbackEvent.getArguments().getString(0);
                notifications.create()
                        .withCaption(value)
                        .withPosition(Notifications.Position.BOTTOM_RIGHT)
                        .show();
            });
        }
    
        class QuillState {
            public Map<String, Object> options;
        }
    }

Как результат, мы видим компонент Quill Rich Text Editor на экране приложения:

jsComponent example

Другой пример интеграции сторонней JavaScript-библиотеки смотрите в разделе Подключение JavaScript библиотеки.