SapUI5: Играем с моделью.
Зачастую нам необходимо хранить, передавать, использовать какие-либо данные внутри SapUI5 приложения.
Например, мы хотим сделать небольшой календарь для трех лет, а отображать мы будем только один год.
Для этого нам нужны:
- Предыдущий год.
- Текущий год.
- Следующий год.
Сохранить их и при каком-то действии (например, клик на кнопку) помечать какой год у нас выбран.
Лучший способ это сделать — создать модель:
Получим текущий год, рассчитаем предыдущий и следующий.
Создадим массив и установим модель.
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 | //Получаем текущий, предыдущий и следующий год var d = new Date(); var currentYear = parseInt(d.getFullYear()); var prevYear = parseInt(d.getFullYear() - 1); var nextYear = parseInt(d.getFullYear() + 1); //Создаем массив var year = { "items": [{ "key": prevYear, "load": false }, { "key": currentYear, "load": false }, { "key": nextYear, "load": false }], "desc": currentYear }; //Создаем модель с именем yearModel var oModelYear = new sap.ui.model.json.JSONModel(); //Добавим в модель выше созданный массив oModelYear.setData(year); //установим модель с именем yearModel this.getOwnerComponent().setModel(oModelYear, "yearModel"); |
Посмотрим что представляет из себя наша модель:
- Key — год.
- load — флаг. Был ли загружен (выбран) когда-то уже данный год или нет.
- В desc храниться выбранный год.
На этом подготовка закончена! Перейдем к манипуляциям с моделью!
Получить значение из модели (getProperty).
Если необходимо получить значение из модели:
1 2 3 4 5 6 7 8 | //Получаем компонент var oComp = this.getOwnerComponent ? this.getOwnerComponent() : this; //Получаем модель var oModel = oComp.getModel("yearModel"); //Получаем значение desc из данной модели (getProperty) var oSelYear = oModel.getProperty("/desc"); |
Записать значение в модель (setProperty).
При необходимости записать данные в модель
1 2 3 4 5 | //получили модель var oModelYearSel = this.getOwnerComponent ? this.getOwnerComponent().getModel("yearModel") : this.getModel("yearModel"); //установили значение desc = currentYear, currentYear предварительно сделали строкой oModelYearSel.setProperty( "/desc", currentYear.toString() ); |
Работа с массивом.
Хорошо, пробежимся по массиву items:
1 2 3 4 5 6 7 8 9 | var model = that.getOwnerComponent() ? that.getOwnerComponent().getModel("yearModel") : that.getModel("yearModel"); var modelData = model.getProperty("/items"); //проверяем, является ли modelData массивом, если да то выполняется цикл if (modelData instanceof Array) { modelData.forEach( function(oValue, i) { // обращаемся к элементам как oValue.key, oValue.load }); } |
Конструкция выше плохая :), почему?
1) Возникают проблемы с областью видимости. Внутри function(oValue, i) вы не сможете использовать переменные, которые объявили в данном методе, в котором у вас используется данный цикл.
2) forEach медленный!
В IE 11 forEach работает на 75% медленней, нежели чем простой for! (смотрим тут https://jsperf.com/fast-array-foreach)
заменим обычным циклом for:
1 2 3 4 5 6 7 8 9 | var model = that.getOwnerComponent() ? that.getOwnerComponent().getModel("yearModel") : that.getModel("yearModel"); var modelData = model.getProperty("/items"); //проверяем, является ли modelData массивом, если да то выполняется цикл if (modelData instanceof Array) { for (var i = 0; i < modelData.length; i++) { // обращаемся к элементам как modelData[i].key, modelData[i].load } } |
А можем обратиться напрямую к определенному элементу без циклов:
1 2 3 4 | var model = that.getOwnerComponent() ? that.getOwnerComponent().getModel("yearModel") : that.getModel("yearModel"); var modelData = model.getProperty("/items"); // обращаемся ко второму элементу как modelData[1], modelData[1].key итп |
Если вложенность большая, то используем следующим образом:
1 | var modelData = model.getProperty("/items/item1/item2"); |
так же можно получить доступ и к элементу массива (например, первому (нулевой элемент) ):
1 | var modelData = model.getProperty("/items/item1/item2/0"); |