SapUI5: Передача объекта, текста из одного контроллера в другой в рамках одного приложения
Представим ситуацию, при загрузке приложения вы получили массив данных. На странице открываете диалоговое окно, у которого контроллер другой, нежели тот, в котором вы получили данные. Получается ситуация, когда необходимо получить данные в контроллере из другого контроллера. Посмотрим как это можно сделать!
Пример приложения, которое используется в данном посте — https://github.com/kannade/sapui5_transfer_data/.
Передаем данные используя модель
Самый логичный и удобный способ передачи данных между контроллерами — модель!
Как создавать модель, заполнять ее и читать мы уже учились тут https://nickcode.ru/sapui5/sapui5-igraem-s-modelyu.html.
Пройдемся кратко по основным моментам.
В модель мы можем записать как обычный текст:
//Получаем текущий, предыдущий и следующий год var d = new Date(); var currentYear = parseInt(d.getFullYear(), 10); var prevYear = parseInt(d.getFullYear() - 1, 10); var nextYear = parseInt(d.getFullYear() + 1, 10); //Первый вариант записи - setProperty var testModel = this.getModel("testmodel"); testModel.setProperty("/items/0/key", prevYear.toString()); testModel.setProperty("/items/1/key", currentYear.toString()); testModel.setProperty("/items/2/key", nextYear.toString()); //Второй вариант записи var aData = testModel.getData(); for (var i = 0; i < aData.items.length; i++) { aData.items[i].load = true; } testModel.refresh(); |
затем вывести его:
var oComp = this.getOwnerComponent(); //компонент, на который забиндина наша модель var testModel = oComp.getModel("testmodel"); // получили модель var aData = testModel.getData(); //массив данных модели //достанем текст из модели и поместим его в Label this.getView().byId("oneLabel").setText(aData.items[0].key); |
так и можем передать объект:
//Установим объект через модель var oLabel2 = new sap.m.Label({ text: "Label from Model from Component" }); testModel.setProperty("/desc", oLabel2); |
и вывести его:
//достанем объект из модели var verticalL = this.getView().byId("verL"); var oLabel2 = testModel.getProperty("/desc"); verticalL.addContent(oLabel2); |
Передаем данные используя третий файл
Можно передавать данные, используя некую прокладку из третьего файла, который будет принимать значение, которое нам надо сохранить, а затем отдавать его в другой контроллер.
В качестве такого файла будем использовать Utils.js:
sap.ui.define([], function() { "use strict"; var _objPernr = null; return { //сохраняем табельный номер setPernr: function(objPernr) { _objPernr = objPernr; }, //возвращаем ранее сохраненный табельный номер getPernr: function() { return _objPernr; } }; }); |
Посмотрим как это работает!
Прежде всего не забываем подключить Utils.js там, где мы хотим его использовать:
sap.ui.define([ "sap/ui/core/mvc/Controller", "transfer/info/model/Utils",], function(Controller, Utils) { "use strict"; |
Сохраняем текст:
//Установим текст через Utils Utils.setPernr("00001234"); |
Отдаем текст:
//достанем текст из utill.js this.getView().byId("threeLabel").setText(Utils.getPernr()); |
Сохраняем объект:
//Установим объект через Utils var oLabel = new sap.m.Label({ text: "Label from Component" }); Utils.setOLabel(oLabel); //Установим объект через Utils var oInput = new sap.m.Input({ value: "Input from Component" }); Utils.setOInput(oInput); |
Отдаем объект:
//достанем объекты из utill.js var oSimpleForm = this.getView().byId("SimpleFormChange354"); var oInput = Utils.getOInput(); var oLabel = Utils.getOLabel(); oSimpleForm.addContent(oLabel); oSimpleForm.addContent(oInput); |
Передаем данные используя глобальный объект
Третий вариант не рекомендуется к использованию, но тоже имеет право на жизнь.
Сохраняем текст и объект:
//установим текст и объект глобально var oLabel3 = new sap.m.Label({ text: "Global Label from Component" }); jQuery.sap.getObject("sap.alfa.dataBinding", 0); sap.alfa.dataBinding = { key1: "Тест текст из глобального объекта", key2: oLabel3 }; |
Отдаем текст и объект:
//достанем текст из глобального объекта this.getView().byId("twoLabel").setText(sap.alfa.dataBinding.key1); //Достанем объект из глобального объекта verticalL.addContent(sap.alfa.dataBinding.key2); |
Передача события между двумя контроллерами / компонентами (EventBus).
Бывает так, что в приложении используется другой компонент:
<core:componentcontainer height="100%" id="list" propagateModel="true" name="component.Tree" usage="treeF4" settings="{ oDataModel : 'oTreePeopleModel' }" async="true" class="treeContainer"></core:componentcontainer> |
в manifest.json :
"sap.ui5": { … "componentUsages": { "treeF4": { "name": "component.Tree", "settings": { "url": "/sap/bc/opu/odata" }, "componentData": "{ hhelo }" } } } |
Надо связать два компонента.
Например, когда происходит какое-то событие в component.Tree, передавать его в основное приложение.
Поможет нам EventBus!
Вернемся к нашему примеру и посмотрим как использовать EventBus в SapUI5 и передать информацию или объект из одного приложения / контроллера в другой!
Передадим событие с переменной d, в которую чуть выше мы записали объект с текущей датой (var d = new Date();)
//Передадим событие в другой контроллер var oEventBus = sap.ui.getCore().getEventBus(); oEventBus.publish( "way1", "afterInitComp", d ); |
, где way1 — канал, afterInitComp — название события, d — передаваемый объект.
перейдем в другой контроллер и подпишимся на событие
onInit: function () { // подписываемся на событие var oEventBus = sap.ui.getCore().getEventBus(); oEventBus.subscribe( "way1", //канал "afterInitComp", //название события this.onAfterInitComp, //вызываем метод onAfterInitComp в данном (this) контроллере this ); }, //объявили метод, который будет вызываться, при отправке события из компонента onAfterInitComp: function (channel, event, item) { MessageToast.show(item); } |
Вот и все! При загрузке приложения oEventBus.publish будет отправлять событие, а из другого компонента можно подписаться oEventBus.subscribe на это событие и вызывать какой-либо метод.
Чуть поподробней про EventBus можно почитать тут — https://blogs.sap.com/2015/10/25/openui5-sapui5-communication-between-controllers-using-publish-and-subscribe-from-eventbus/ и тут https://stackoverflow.com/questions/25382988/how-to-use-geteventbus-method-in-sapui5.
Такие дела :).