Урок 7. SapUI5: Диалоговые окна и фрагменты + i18n

В уроке 4 мы познакомились с фрагментами и использовали их не по назначению.

Фрагменты надо использовать в повторяющихся элементах пользовательского интерфейса, где нет необходимости использовать логику (фрагменты не имеют собственного контроллера).

Один из самых лучших примеров использования фрагментов — Диалоговые окна (sap.m.Dialog)!

Пример — https://github.com/kannade/dialog_sapui5.

Создадим новый проект.
Подключим в index.html представление sap.training.view.Main ({пространство имен sap.training}/view/Main.view.xml):

/dialog_sapui5/blob/master/webapp/index.html
1
2
3
4
5
6
7
8
9
var oView = sap.ui.view({
    id: "idMain",
    viewName: "sap.training.view.Main",
    type: sap.ui.core.mvc.ViewType.XML
});
 
oView.placeAt("content");

В представлении sap.training.view.Main ({пространство имен sap.training}/view/Main.view.xml) сделаем кнопку с событием press=»onOpenDialog» и текстовое поле:

/dialog_sapui5/blob/master/webapp/view/Main.view.xml
1
2
3
4
5
<button press="onOpenDialog" text="{i18n>openDialog}">
<text id="idText"></text></button>

Опишем фрагмент sap.training.view.Dialog ({пространство имен sap.training}/view/Dialog.fragment.xml), который будет отвечать за само диалоговое окно:

/dialog_sapui5/blob/master/webapp/view/Dialog.fragment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<core:fragmentdefinition xmlns:core="sap.ui.core" xmlns:f="sap.ui.layout.form" xmlns="sap.m">
	<dialog title="Диалоговое окно в фрагменте">
		<beginbutton>
			<button press="onCloseDialog" text="{i18n>dialogClose}">
		</button></beginbutton>
		<content>
			<f:simpleform>
				<f:content>
					<label text="Имя"></label>
					<input id="idInput">
				</f:content>
			</f:simpleform>
		</content>
	</dialog>
</core:fragmentdefinition>

А теперь перейдем к контроллеру sap.training.controller.Main ({пространство имен sap.training}/controller/Main.controller.js).

Первое — создадим модель i18n.

В представлениях для вывода текста мы используем такие конструкции {i18n>dialogClose}.

«i18n» — сокращение от английского слова «internationalization» (Интернационализация).

«i18n» — это модель, упрощающая адаптацию приложения к языковым особенностям региона пользователя.
В данном примере в файле i18n определим две фразы:

/dialog_sapui5/blob/master/webapp/i18n/i18n.properties
1
2
openDialog=Открыть диалоговое окно
dialogClose=Ok

Так как главное представление мы задали напрямую, а не через Shell (ComponentContainer), то i18n придется создать принудительно:

/dialog_sapui5/blob/master/webapp/controller/Main.controller.js
1
2
3
4
5
6
7
8
9
10
onInit: function() {
			//так как подключаем не shell, создадим модель i18n
			var oResourceModel = new sap.ui.model.resource.ResourceModel({				bundleName: "sap.training.i18n.i18n"
			});
 
			// Устанавливаем для ядра с именем i18n
			sap.ui.getCore().setModel(oResourceModel, "i18n"); 
		},

Переходим к самому главному, определяем три метода для работы с диалоговым окном

/dialog_sapui5/blob/master/webapp/controller/Main.controller.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
_getDialog: function() {	 if (!this._oDialog) {
		 //создаем фрагмент
		 this._oDialog = sap.ui.xmlfragment("idFrag", "sap.training.view.Dialog", this);
 
		 //Добавляем зависимости для корректного отображения модели
		 this.getView().addDependent(this._oDialog);
			}
		 return this._oDialog;
		},
 
onOpenDialog: function() {	 this._getDialog().open();
		},
 
onCloseDialog: function() {	 this._getDialog().close();
 
                //обращаемся к полю ввода, расположенного в фрагменте
		var oInput = sap.ui.core.Fragment.byId("idFrag", "idInput");
		var oText = this.getView().byId("idText");
		oText.setText("Привет " + oInput.getValue());
		}
  • _getDialog — создание самого диалогового окна
  • onOpenDialog — открыть диалоговое окно
  • onOpenDialog — закрыть диалоговое окно + вывести информацию из диалогового окна (sap.ui.core.Fragment.byId(«idFrag», «idInput») — получаем ссылку на элемент idInput во фрагменте idFrag)

С этим примером все :).
Диалоговое окно при клике открывается и закрывается, но не верьте мне на слово, попробуйте САМИ!

P.S.: Фрагменту можно задать собственный контроллер!

Посмотрите на 4 строку

/dialog_sapui5/blob/master/webapp/controller/Main.controller.js
1
2
3
4
_getDialog: function() {
	 if (!this._oDialog) {
		 //создаем фрагмент
		 this._oDialog = sap.ui.xmlfragment("idFrag", "sap.training.view.Dialog", this);
/dialog_sapui5/blob/master/webapp/controller/Main.controller.js
1
2
3
4
_getDialog: function() {
	 if (!this._oDialog) {
		 //создаем фрагмент
		 this._oDialog = sap.ui.xmlfragment("idFrag", "sap.training.view.Dialog", sap.ui.controller("sap.training.controller.FragCont"));

В таком случае фрагмент будет иметь контроллер /controller/FragCont.controller.js.

Update 09.06.2020

Представленная выше форма создания фрагмента имеет место быть и сейчас, но тренды меняются и теперь «модно» использовать sap.ui.core.Fragment.load!

В качестве примера, мы возьмем проект https://github.com/kannade/dialog_sapui5 и переделаем создание фрагмента при помощи новой конструкции :):

/sapui5_fragment_load/blob/master/webapp/controller/Main.controller.js
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
_getDialog: function () {	var promise = new Promise(function (resolve, reject) {
		if (!this._oDialog) {
			//Зугразим фрагмент
			Fragment.load({
				id: "idFrag", //id
				type: "XML", // тип фрагмента
				name: "sap.training.view.Dialog", // путь до фрагмента
				controller: this //укажем контроллер, чтобы правильно отрабатывала кнопка "закрыть в диалоговом окне"
			}).then(function (oDialog) {
				resolve(oDialog);
			});
		} else {
			resolve(this._oDialog);
		}
	}.bind(this));
 
	return promise;
},
onOpenDialog: function () {	this._getDialog().then(function (oDialog) {
		this._oDialog = oDialog;
		//Добавляем зависимости для корректного отображения модели
		this.getView().addDependent(this._oDialog);
		this._oDialog.open(); // откроем
	}.bind(this));
},
 
onCloseDialog: function () {	this._getDialog().then(function (oDialog) {
		this._oDialog.close(); //закроем
 
		//обращаемся к полю ввода, расположенного в фрагменте
		var oInput = Fragment.byId("idFrag", "idInput");
		var oText = this.getView().byId("idText");
 
		oText.setText("Привет " + oInput.getValue());
	}.bind(this));
}

Переделанная версия — https://github.com/kannade/sapui5_fragment_load.