注意:
尽可能的使用图标字体而不是图像,因为它们是可伸缩的,没有质量损失(矢量图形),不需要单独加载。
我们把所有跨多个控制器使用的资源放在单独的模块中。
webapp/view/HelloPanel.view.xml
<mvc:View
controllerName="sap.ui.demo.walkthrough.controller.HelloPanel"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Panel
headerText="{i18n>helloPanelTitle}"
class="sapUiResponsiveMargin"
width="auto" >
<content>
<Button
id="helloDialogButton"
**icon="sap-icon://world"**
text="{i18n>openDialogButtonText}"
press=".onOpenDialog"
class="sapUiSmallMarginEnd"/>
<Button
text="{i18n>showHelloButtonText}"
press=".onShowHello"
class="myCustomButton"/>
<Input
value="{/recipient/name}"
valueLiveUpdate="true"
width="60%"/>
<FormattedText
htmlText="Hello {/recipient/name}"
class="sapUiSmallMargin sapThemeHighlight-asColor myCustomText"/>
</content>
</Panel>
</mvc:View>
我们向打开对话框的按钮添加一个图标。sap-icon://协议表示从这个路径加载图标。
您可以使用图标管理器工具查找其他图标。要调用任何图标,请使用它的名称,在sap-icon的图标管理器中列出://。
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core" >
<Dialog
id="helloDialog"
title ="Hello {/recipient/name}">
<content>
<core:Icon
src="sap-icon://hello-world"
size="8rem"
class="sapUiMediumMargin"/>
</content>
<beginButton>
<Button
text="{i18n>dialogCloseButtonText}"
press=".onCloseDialog"/>
</beginButton>
</Dialog>
</core:FragmentDefinition>
在对话框片段中,我们将一个图标控件添加到对话框的内容聚合中。图标字体还带有一个“Hello World”图标,这对我们来说是完美的。我们还定义了图标的大小,并在其上设置了中等距。
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel",
**"./controller/HelloDialog"**
], function (UIComponent, JSONModel, **HelloDialog**) {
"use strict";
return UIComponent.extend("sap.ui.demo.walkthrough.Component", {
metadata : {
manifest : "json"
},
init : function () {
// call the init function of the parent
UIComponent.prototype.init.apply(this, arguments);
// set data model
var oData = {
recipient : {
name : "World"
}
};
var oModel = new JSONModel(oData);
this.setModel(oModel);
**// set dialog
this._helloDialog = new HelloDialog(this.getRootControl());
},
exit : function() {
this._helloDialog.destroy();
delete this._helloDialog;
},
openHelloDialog : function () {
this._helloDialog.open();**
}
});
});
重用对话框
对话框实例化被重构为一个新的助手对象,该对象存储在组件的私有属性中。
对于HelloDialog.js 对象的实例化,我们必须传递添加对话框的视图实例(参见下面对象HelloDialog.js实现中的方法addDependent)。
我们想把重用对话框和应用的根视图的生命周期连接起来,所以我们把根视图的一个实例传递给构造函数。可以通过调用组件的getRootControl方法来检索它。
根视图在manifest.json 文件重定义,我们的根视图是sap.ui.demo.walkthrough.view.App。从组件中,可以在运行时通过访问rootControl聚合来检索根视图。
为了能够从其他控制器打开对话框,我们实现了一个重用函数openHelloDialog,它调用helper对象的open方法。通过这样做,我们还将重用对话框的实现细节从应用程序编码中解耦出来。
到目前为止,我们向组件添加了新的属性_helloDialog,并为它分配了HelloDialog对象的一个实例。我们希望确保在组件销毁时,分配给这个helper对象的内存被释放。否则,我们的应用程序可能会导致内存泄漏。
为此,我们使用退出函数。SAPUI5框架在销毁组件时调用指定的退出函数。我们调用HelloDialog的destroy函数来清理helper类并结束它的生命周期。然而,实例本身仍然存在于浏览器内存中。因此,我们通过调用delete this_HelloDialog来删除实例的引用,浏览器的垃圾回收可以清理它的内存。
我们不需要销毁我们创建的JSONModel实例,因为我们用setModel函数将它分配给了组件。SAPUI5框架会将其与组件一起销毁。
webapp/controller/HelloDialog.js (New)
sap.ui.define([
"sap/ui/base/ManagedObject",
"sap/ui/core/Fragment"
], function (ManagedObject, Fragment) {
"use strict";
return ManagedObject.extend("sap.ui.demo.walkthrough.controller.HelloDialog", {
constructor : function (oView) {
this._oView = oView;
},
exit : function () {
delete this._oView;
},
open : function () {
var oView = this._oView;
// create dialog lazily
if (!oView.byId("helloDialog")) {
var oFragmentController = {
onCloseDialog : function () {
oView.byId("helloDialog").close();
}
};
// load asynchronous XML fragment
Fragment.load({
id: oView.getId(),
name: "sap.ui.demo.walkthrough.view.HelloDialog",
controller: oFragmentController
}).then(function (oDialog) {
// connect dialog to the root view of this component (models, lifecycle)
oView.addDependent(oDialog);
oDialog.open();
});
} else {
oView.byId("helloDialog").open();
}
}
});
});
HelloDialog重用对象的实现扩展了sap.ui.base.ManagedObject对象,从而继承了SAPUI5的一些核心功能。
我们的open方法是从HelloPanel控制器重构出来的,并像前面的步骤一样实例化对话框片段。
我们没有传递一个控制器作为函数sap.ui.xmlfragment的第三个参数,而是传递了一个本地helper对象ofragmentcontroller,它包含了片段所需的事件处理函数onCloseDialog。
onOpenDialog方法现在通过调用helper方法getOwnerComponent来访问它的组件。当调用重用对象的open方法时,我们在当前视图中将其连接到对话框中。
onCloseDialog事件处理程序只是从HelloPanel控制器移动到重用对象。
我们还添加了一个退出函数,就像我们在组件中做的那样,当对象被销毁时,它将被自动调用。为了释放helper对象中所有已分配的内存,我们删除保存视图引用的属性。视图本身会被组件销毁,所以我们不需要为此操心。
webapp/controller/HelloPanel.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast"
], function (Controller, MessageToast) {
"use strict";
return Controller.extend("sap.ui.demo.walkthrough.controller.HelloPanel", {
onShowHello : function () {
// read msg from i18n model
var oBundle = this.getView().getModel("i18n").getResourceBundle();
var sRecipient = this.getView().getModel().getProperty("/recipient/name");
var sMsg = oBundle.getText("helloMsg", [sRecipient]);
// show message
MessageToast.show(sMsg);
},
onOpenDialog : function () {
this.getOwnerComponent().openHelloDialog();
}
});
});
onOpenDialog方法现在通过调用helper方法getOwnerComponent来访问它的组件。当调用重用对象的open方法时,我们在当前视图中将其连接到对话框中。
webapp/view/App.view.xml
<mvc:View
controllerName="sap.ui.demo.walkthrough.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
displayBlock="true">
<Shell>
<App class="myAppDemoWT">
<pages>
<Page title="{i18n>homePageTitle}">
<headerContent>
<Button
icon="sap-icon://hello-world"
press=".onOpenDialog"/>
</headerContent>
<content>
<mvc:XMLView viewName="sap.ui.demo.walkthrough.view.HelloPanel"/>
</content>
</Page>
</pages>
</App>
</Shell>
</mvc:View>
们在应用程序视图的头区域添加了一个按钮来显示hello world对话框的重用。当按下按钮时,对话框将像我们之前在面板中创建的按钮一样打开。
webapp/controller/App.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("sap.ui.demo.walkthrough.controller.App", {
onOpenDialog : function () {
this.getOwnerComponent().openHelloDialog();
}
});
});
我们还将onOpenDialog方法添加到应用控制器中,这样对话框就会以当前视图的引用打开。