在此步骤中,我们将扩展重用概念,并在组件级别调用对话框。
在步骤16中,我们创建了一个对话框作为片段,以使其可跨视图或跨整个应用程序重用。但是我们将检索对话框实例和分别打开和关闭对话框实例的逻辑放置在HelloPanel视图的控制器中。坚持这种方法需要将代码复制并粘贴到需要对话框的每个视图的控制器中。这将导致我们希望避免的不必要的代码冗余。
在这一步中,我们实现了这个问题的解决方案:扩展重用概念并在组件级别调用对话框。
Preview
The dialog is now opened by the component (no visual changes to last step)
Coding
You can view and download all files at Walkthrough - Step 19.
webapp/Component.js
sap.ui.define([ "sap/ui/core/UIComponent", "sap/ui/model/json/JSONModel", "sap/ui/demo/walkthrough/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(); } }); });
对话框实例化被重构到一个新的helper对象,该对象存储在组件的私有属性中。对于助手对象的实例化,我们必须传递添加对话框的视图实例(请参阅下面的帮助对象HelloDialo.JS实现中调用addDependent的方法)。
我们希望将重用对话框连接到应用程序根视图的生命周期,因此我们将根视图的一个实例传递给构造函数。它可以通过调用组件的getRootControl方法来检索。
请注意:如清单中的参数rootView中定义的。json文件,我们的根视图是sap.ui.demo.walk .view. app。从组件中,可以通过访问rootControl聚合在运行时检索根视图。
为了能够从其他控制器打开对话框,我们实现了一个重用函数openHelloDialog,它调用我们的helper对象的open方法。通过这样做,我们还将重用对话框的实现细节从应用程序编码中分离出来。
到目前为止,我们向组件添加了新的属性_helloDialog,并将HelloDialog对象的一个实例分配给它。我们希望确保在组件被销毁时,为这个helper对象分配的内存被释放。否则我们的应用程序可能会导致内存泄漏。
为此,我们使用出口exit挂钩。SAPUI5框架在销毁组件时调用分配给退出的函数。我们调用HelloDialog的destroy函数来清理helper类并结束它的生命周期。然而,实例本身仍然存在于浏览器内存中。因此,我们通过调用delete this来删除对HelloDialog实例的引用。_helloDialog和垃圾回收的浏览器可以清理其内存。
请注意:我们不需要销毁我们创建的JSONModel实例,因为我们使用setModel函数将它分配给了组件。SAPUI5框架将与组件一起摧毁它。
webapp/controller/HelloDialog.js (New)
sap.ui.define([ "sap/ui/base/ManagedObject" ], function (ManagedObject) { "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; var oDialog = oView.byId("helloDialog"); // create dialog lazily if (!oDialog) { var oFragmentController = { onCloseDialog : function () { oDialog.close(); } }; // create dialog via fragment factory oDialog = sap.ui.xmlfragment(oView.getId(), "sap.ui.demo.walkthrough.view.HelloDialog", oFragmentController); // connect dialog to the root view of this component (models, lifecycle) oView.addDependent(oDialog); } oDialog.open(); } }); });
我们的open方法是从HelloPanel控制器中重构出来的,并按照前面的步骤实例化我们的对话片段。HelloDialog重用对象的实现扩展了sap.ui.base。ManagedObject对象继承了SAPUI5的一些核心功能。
请注意:我们不会将控制器作为第三个参数传递给函数sa .ui。而是一个本地帮助对象oFragmentContoller,它包含了片段所需的事件处理函数onCloseDialog。
open方法现在包含我们的对话框实例化。第一次调用open方法时,将实例化对话框。该方法的oView参数用于将当前视图连接到对话框。稍后我们将在控制器中调用该对象的open方法。
onCloseDialog事件处理程序简单地从HelloPanel控制器移动到重用对象。
我们还添加了一个exit函数,就像在组件中所做的那样,当对象被销毁时,该函数将被自动调用。为了释放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方法现在通过调用助手方法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"> <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> </mvc:View>
我们将一个按钮添加到app视图的标题区域,以显示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添加到app控制器中,这样对话框将在引用当前视图的情况下打开.
Conventions
将跨多个控制器使用的所有资产放在单独的模块中。
Parent topic: Walkthrough
Previous: Step 18: Icons
Next: Step 20: Aggregation Binding
Related Information