Step 19 Reuse Dialogs

在step16里,对话框是被集成在view和controller里了。不够共通。
这次把对话框,共通到component级别,方便别的view使用。

webapp/Component.js

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 : {
			interfaces: ["sap.ui.core.IAsyncContentCreation"],
			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();
		}
	});
});

使用"./controller/HelloDialog"作为helper object。
this._helloDialog = new HelloDialog(this.getRootControl());
this.getRootControl()的返回值是rootView,是把rootView作为参数传递给HelloDialog.js的构造函数,因为渲染对话框的时候,必须告诉它是在哪个view上渲染,还因为需要连接对话框和rootView的生命周期。
然后把创建好的HelloDialog对象放在_helloDialog属性里保存。

constructor : function (oView) {
			this._oView = oView;
		},

当Component的生命周期结束后,会自动调用exit方法。
HelloDialog类是ManagedObject对象的子类,this._helloDialog.destroy()是为了并结束它的生命周期。调用它的析构函数。
delete this._helloDialog;是为了释放Component的_helloDialog所占用的内存。delete后内存引用计数减一。浏览器的垃圾回收,看到它的引用计数为0,会自动释放它所占用的内存。
openHelloDialog函数是,当点击某个按钮后调用的函数,目的是打开对话框。

我们不需要destroy JSONModel对象,因为调用了setModel SAPUI5 framework会在destroy component对象的时候,destroy它。

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 (!this.pDialog) {
				var oFragmentController = {
					onCloseDialog : function () {
						oView.byId("helloDialog").close();
					}
				};
				// load asynchronous XML fragment
				this.pDialog = 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);
					return oDialog;
				});
			} 
			this.pDialog.then(function(oDialog) {
				oDialog.open();
			});
		}

	});

});

1,继承自ManagedObject基类。
2,构造函数和析构函数,由于在构造函数里增加了rootView的引用计数,所以在exit(析构函数)里delete rootView,使rootView引用计数减一。
3,Fragment的controller,点击对话框的OK按钮会调用它。

var oFragmentController = {
					onCloseDialog : function () {
						oView.byId("helloDialog").close();
					}
				};

4,连接rootView和对话框的生命周期。oView.addDependent(oDialog);

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();
		}
	});
});

this.getOwnerComponent():返回它的component对象

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>

在header的最右边加一个按钮。

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();
		}
	});

});

在rootVIew的controller里添加对应的点击事件。

约定:如果一个组件是被多个controller使用的话,那么把它放到单独的module里。

posted @ 2021-08-27 17:05  小石王  阅读(577)  评论(1编辑  收藏  举报