Урок 5. SapUI5: Собственные типы данных. Property binding.
Продолжим работать над предыдущим проектом (https://github.com/kannade/layout_sapui5/).
В sapui5 есть встроенные типы данных, например sap.ui.model.type.String, которому мы ограничили длину до 5 символов:
1 | <input id="first" value="{ path: 'odata/>/enabled', type: 'sap.ui.model.type.String', constraints: {minLength : 1, maxLength : 5} }"> |
но, sapui5 предоставляет возможность сделать пользовательские типы, чем мы сейчас и займемся.
Сделаем тип, который будет содержать в себе 6 цифр. После каждых 2-х цифр должен следовать символ «-«.
Создадим файл {пространство имен}/model/type/digits.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | sap.ui.define(["sap/ui/model/SimpleType", "sap/ui/model/ValidateException"], function(SimpleType, ValidateException) { return SimpleType.extend("hello.layout.model.type.digits", { formatValue: function(sValue, sInternalType) { //добавим "-" после каждых двух цифр var aDigits = sValue.split(""); var sOutput = ""; $.each(aDigits, function(i, iDigit) { if ((i > 0) && (i % 2 === 0)) { sOutput = sOutput + "-" + iDigit; } else { sOutput += iDigit; } }); return sOutput; }, parseValue: function(sValue) { return sValue.replace(/-/g, ""); }, validateValue: function(sValue) { var aDigits = sValue.split(""); if (aDigits.length !== 6) { throw new ValidateException(sValue + " не корректный номер телефона"); } } }); }); |
- formatValue — метод для форматирования значение на экране пользователя. Например, если после каждых двух цифр нам надо ставить тире, то эта логика настраивается в formatValue.
- parseValue — метод для внутреннего представления. Допустим ввели номер телефона «34-14-24», но в JS мы должны представить эту строку как «341424».
- validateValue — метод валидации.
parseValue вызывается при вводе любого символа в поле ввода, затем отрабатывает validateValue и если ошибки отсутствуют сработает formatValue.
Загрузим только что созданный тип в контроллере:
1 2 3 4 5 6 7 8 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast", "sap/ui/Device", "hello/layout/model/formatter", "hello/layout/model/type/digits"], function(Controller, MessageToast, Device, formatter, Digits) { "use strict"; |
Применим его для поля ввода в XML представлении:
1 2 3 4 5 6 7 8 9 10 11 | <input enabled="{odata/>/enabled}" value="{ path: 'odata>/name', type: 'hello.layout.model.type.digits' }" valueLiveUpdate="true"><layoutdata> <l:griddata span="L4 M6 S6"></l:griddata> </layoutdata> <text text="{odata>/name}"> <layoutdata> <l:griddata span="L4 M6 S6"></l:griddata> </layoutdata> </text> |
Что мы сделали этим кодом:
- Присвоили первому Input пользовательский тип hello.layout.model.type.digits.
- Прописали свойство valueLiveUpdate=»true», благодаря которому в Text значения будут меняться при любом изменении значения в Input.
- Забиндили значение из Input на модель «odata» (которую мы описали в 4 уроке): path: ‘odata>/name’.
- В Text реализовали Property Binding. Присвоили свойству text значение text=»{odata>/name}».
При любом изменении поля Input, значения в Text также будут меняться!
Плюс, если значение из поля не будет соответствовать маске xx-xx-xx (где x — цифра), мы получим ошибку:
Как отслеживать ошибки в SapUI5?
Хорошо, а теперь давайте сделаем так, чтобы при нажатии на кнопку происходила проверка поля. Если есть ошибка — выводилась ошибка, если все хорошо — выводилось значение поля.
В методе onInit контроллера включаем отслеживание ошибок:
1 2 | // Register the view with the message manager sap.ui.getCore().getMessageManager().registerObject(this.getView(), true); |
На кнопку повесим событие onPressSubmit:
1 2 | <button text="Submit" icon="sap-icon://paper-plane" press="onPressSubmit"> </button> |
Опишем событие в onPressSubmit контроллере:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | onPressSubmit: function() { var arr = sap.ui.getCore().getMessageManager().getMessageModel().oData; for (var i = 0; i < arr.length; i++) { if (arr[i].code == undefined && arr[i].type == sap.ui.core.MessageType.Error) { var sTarget = arr[i].getTarget(); var oElem = sap.ui.getCore().byId(sTarget.substr(0, sTarget.indexOf("/"))); if (oElem) { oElem.focus(); } MessageToast.show(arr[i].message); return true; } } MessageToast.show(this.getView().byId("idFormFrag--first").getValue() + " " + this.getView().getModel("odata").getData().name + sap.ui.getCore().byId("__xmlview0--idFormFrag--second").getValue() ); } |
Итак, что тут у нас происходит…
Мы объявляем массив arr, в каждом элементе которого у нас содержится ошибка.
Далее перебираем все ошибки (элементы массива) с определенным кодом (undefined) и типом (sap.ui.core.MessageType.Error). Переводим фокус на элемент с ошибкой (oElem.focus()) и выводим сообщение с текстом ошибки.
Если массив ошибок пустой, то выводим сообщение:
- Получаем значение из первого поля (в примере поле Num 1, с ограничением по количеству символов (до 5)) — this.getView().byId(«idFormFrag—first»).getValue()
- + значение из модели (наши 4 цифры) — this.getView().getModel(«odata»).getData().name
- + значение из третьего поля — sap.ui.getCore().byId(«__xmlview0—idFormFrag—second»).getValue()
Каждое из трех значений мы получили разными способами:
- this.getView().byId(«idFormFrag—first»).getValue() — получили значение, обратившись к элементу через его представление.
- this.getView().getModel(«odata»).getData().name — получаем значение из модели (ЛУЧШИЙ ВЫБОР).
- sap.ui.getCore().byId(«__xmlview0—idFormFrag—second»).getValue() — получили значение, обратившись к элементу напрямую по id.