SapUI5: Как поменять стандартный файл/метод
SapUI5 позволяет решать ряд типичных задач. Но как только возникают какие-то не стандартные потребности, приходиться переходить на JS в связке с JQuery. В таких задачах зачастую необходимо отредактировать стандартный элемент управления, метод, библиотеку.
В этом посте посмотрим как можно переписать стандартный файл или переопределить стандартный метод.
Пример, который мы будем рассматривать ниже, можно импортировать в свой WebIDE отсюда https://github.com/kannade/sapui5_redefine.
В примере на экран выведем 4 кнопки:
- Кнопка №1 — самая обычная кнопка sap.m.Button;
- Кнопка №2 — полностью скопируем стандартный элемент в пользовательский и выведем на экран;
- Кнопка №3 — это та же самая кнопка №2, но выведем ее через JS;
- Кнопка №4 — унаследованная стандартная кнопка с измененным методом;
Кнопка №1. Выведем sap.m.Button
Просто нарисуем кнопку:
< Button text="text button 1" /> |
Кнопка №2. Редактируем стандартный элемент управления и выводим в XML.
Итак, мы хотим отредактировать стандартный код элемента управления «Кнопка» (sap.m.Button).
Для этого нам нужно получить исходные коды кнопки (sap/m/Button.js) и скрипта, который эту кнопку рисует (sap/m/ButtonRenderer.js). Скачать их можно либо с официальной страницы OpenUI5 на GitHub — https://github.com/SAP/openui5, либо вытянуть из того ядра, которое подгружается в вашем приложении.
На гитхабе Button.js можно скачать тут https://github.com/SAP/openui5/blob/master/src/sap.m/src/sap/m/Button.js, но проблемы могут возникнуть, если ваша версия SapUI5 отличается от той, которая на гитхабе.
Для копирования исходных файлов из ядра переходим в инструменты разработчика Google Chrome (F12) на вкладку Source, в левой части экрана ищем sapui5.hana.ondemand.com -> resources -> sap -> m -> Button-dbg.js:
Если файл называется Button.js (минифицированный код (удалены пробелы, отступы, переименованы переменные)), а не Button-dbg.js (код для дебага (читаемый код)), попробуйте добавить url параметр sap-ui-debug=true и обновить страницу.
Убираем из названия файлов «-dbg» и копируем их в наш проект в папку controls:
Перейдем в файл Button.js и заменим:
var Button = Control.extend("sap.m.Button", |
на
var Button = Control.extend("nickcode_ru_redefine.controls.Button", |
где nickcode_ru_redefine — наш NameSpace, .controls.Button — путь до файла Button.js.
и поменяем путь загрузки для файла library, так как в исходном варианте sapui5 будет искать данный файл в текущей папке:
sap.ui.define([ 'jquery.sap.global', './library', 'sap/ui/core/Control', |
на
sap.ui.define([ 'jquery.sap.global', 'sap/m/library', 'sap/ui/core/Control', |
Так, теперь отредактируем какой-нибудь метод скопированного элемента управления «Кнопка». Давайте сделаем так, чтобы в момент рисования кнопки, к тексту, который пишется на кнопке, добавлялась какая-либо строка.
Для этого перейдем в sap/m/ButtonRenderer.js и отредактируем тот момент, где для кнопки устанавливается текст:
// write button text if (sText) { oRm.write("<span "); oRm.addClass("sapMBtnContent"); // check if textDirection property is not set to default "Inherit" and add "dir" attribute if (sTextDir !== TextDirection.Inherit) { oRm.writeAttribute("dir", sTextDir.toLowerCase()); } oRm.writeClasses(); oRm.writeAttribute("id", oButton.getId() + "-content"); oRm.write(">"); if (bRenderBDI) { oRm.write("<bdi>"); } //ПРИБАВИМ К ТЕКСТУ СТРОКУ "_123" //oRm.writeEscaped(sText); oRm.writeEscaped(sText + "_123"); if (bRenderBDI) { oRm.write("</bdi>"); } oRm.write("</span>"); } |
Перейдем к представлению и выведем нашу новую кнопку!
<mvc:view controllerName="nickcode_ru_redefine.controller.Main" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:myself="nickcode_ru_redefine.controls"> <app id="idAppControl"> <pages> <page title="{i18n>title}" id="idPage"> <content> <button text="text button 1"></button> <myself:button text="text button 2"></myself:button> </content> </page> </pages> </app> </mvc:view> |
Обратите внимание, что мы определяем новый NameSpace (указываем путь до папки с button.js): xmlns:myself=»nickcode_ru_redefine.controls», а затем рисуем кнопку, используя наш скопированный элемент: <myself:Button text=»text button 2″ />
Кнопка №3. Редактируем стандартный элемент управления и выводим в JS.
Нарисуем кнопку №2, но только в JS:
sap.ui.define([ "sap/ui/core/mvc/Controller", "nickcode_ru_redefine/controls/Button" //путь до скопированной кнопки], function(Controller, Button) { "use strict"; return Controller.extend("nickcode_ru_redefine.controller.Main", { onInit: function() { var oButton = new Button({ //создаем кнопку text: "button_from_js" }); this.getView().byId("idPage").addContent(oButton); //добавляем кнопку на экран } }); }); |
Таким образом можно редактировать практически любые стандартные файлы SapUI5, но только стоит помнить о зависимостях и ссылках на другие стандартные файлы (как это было чуть выше с library).
Кнопка №4. Наследуем стандартный элемент управления и редактируем метод.
Перейдем к 4 кнопки!
Представим, что нам надо отредактировать какой-то один метод элемента управления. В таком случае копировать все файлы к себе в проект не имеет смысла, давайте переопределим только 1 метод!
Создадим файл Button3, в котором расширим стандартный элемент управления sap.m.Button и перепишим стандартный метод setText этого элемента:
sap.ui.define([ 'sap/m/ButtonRenderer' //файл отрисовщик для кнопки ], function( ButtonRenderer ) { "use strict"; //Расширяем стандартный sap.m.Button var Button = sap.m.Button.extend("nickcode_ru_redefine.controls.Button3", { renderer: ButtonRenderer //указываем стандартный скрипт отрисовки элемента }); //Переписываем стандартный метод setText Button.prototype.setText = function(sText) { var sValue = this.getText(); if (sText === null || sText === undefined) { sText = ""; } if (sValue !== sText) { var oDomRef = this.getDomRef("content"); var bShouldSupressRendering = !!oDomRef; // Render control if element is not available in the DOM //При вызове метода setText добавим с тексту кнопки строку "_123" //this.setProperty("text", sText, bShouldSupressRendering); this.setProperty("text", sText + "_123", bShouldSupressRendering); if (bShouldSupressRendering) { // Get text to have the type conversation for non-string values done by the framework sText = this.getText(); oDomRef.innerHTML = jQuery.sap.encodeHTML(sText); this.$("inner").toggleClass("sapMBtnText", !!sText); } } return this; }; return Button; }); |
Попробуем нарисовать кнопку №4 и вызвать переписанный метод setText:
sap.ui.define([ "sap/ui/core/mvc/Controller", "nickcode_ru_redefine/controls/Button", "nickcode_ru_redefine/controls/Button3" //указали путь до унаследованной кнопки], function(Controller, Button, Button3) { "use strict"; return Controller.extend("nickcode_ru_redefine.controller.Main", { onInit: function() { var oButton = new Button({ text: "button_from_js" }); this.getView().byId("idPage").addContent(oButton); //создаем унаследованную кнопку var oButton3 = new Button3({ text: "" }); this.getView().byId("idPage").addContent(oButton3); //Вызываем переписанный метод setText oButton3.setText("button_from_js3"); } }); }); |
Таким образом можно как угодно изменять стандартные элементы управления, стандартную логику SapUI5, визуализацию элементов, да и все, что в голову придет… даже создавать свои комплексные элементы управления, но это тема уже для другого поста ;).
Спасибо, сэкономило кучу времени!
Кажется, сапы не советуют расширять элементы.