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里。