前面介绍了如何把代码转移到Eclipse
,本文将对WebIDE生成的master-detail
模板进行代码的分析,让我们看看这些代码有什么作用。目前WebIDE版本为1.7,这个新版本生成的代码已经和1.4有了很大的不同,如果有朋友还工作在老版本的模板,最好升级一下自己的模板吧。
index.html
页面入口文件, 如果需要放到Fiori Launch Pad中,则此文件不会加载,即如果想使用一些第三方的JS代码,并且想运行在Fiori上,在此文件中加载的第三方JS将不会被加载。
主要代码:
* 页面的标题,会显示在浏览器的标签上
<title>template_md</title>
- 加载UI5组件,指定主题,加载sap.m,指定resource目录等。
<script id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-resourceroots='{"ZTMP_MD": "./"}'>
</script>
- 新建shell,放置在html content部位。
<script>
sap.ui.getCore().attachInit(function() {
new sap.m.Shell({
app: new sap.ui.core.ComponentContainer({
height : "100%",
name : "ZTMP_MD"
})
}).placeAt("content");
});
</script>
2.Component.js
主要用于route定义,model绑定等等。
jQuery.sap.declare("ZTMP_MD.Component");
jQuery.sap.require("ZTMP_MD.MyRouter");
sap.ui.core.UIComponent.extend("ZTMP_MD.Component", {
metadata : {
name : "template_md",
version : "1.0",
includes : [],
dependencies : {
libs : ["sap.m", "sap.ui.layout"],
components : []
},
rootView : "ZTMP_MD.view.App",
config : {
resourceBundle : "i18n/messageBundle.properties",
serviceConfig : {
name: "ZCUSTOMER_SRV",
serviceUrl: "/sap/opu/odata/sap/ZCUSTOMER_SRV/"
}
},
routing : {
config : {
routerClass : ZTMP_MD.MyRouter,
viewType : "XML",
viewPath : "ZTMP_MD.view",
targetAggregation : "detailPages",
clearTarget : false
},
routes : [
{
pattern : "",
name : "main",
view : "Master",
targetAggregation : "masterPages",
targetControl : "idAppControl",
subroutes : [
{
pattern : "{entity}/:tab:",
name : "detail",
view : "Detail"
}
]
},
{
name : "catchallMaster",
view : "Master",
targetAggregation : "masterPages",
targetControl : "idAppControl",
subroutes : [
{
pattern : ":all*:",
name : "catchallDetail",
view : "NotFound",
transition : "show"
}
]
}
]
}
},
init : function() {
sap.ui.core.UIComponent.prototype.init.apply(this, arguments);
var mConfig = this.getMetadata().getConfig();
// Always use absolute paths relative to our own component
// (relative paths will fail if running in the Fiori Launchpad)
var oRootPath = jQuery.sap.getModulePath("ZTMP_MD");
// Set i18n model
var i18nModel = new sap.ui.model.resource.ResourceModel({
bundleUrl : [oRootPath, mConfig.resourceBundle].join("/")
});
this.setModel(i18nModel, "i18n");
var sServiceUrl = mConfig.serviceConfig.serviceUrl;
//This code is only needed for testing the application when there is no local proxy available
var bIsMocked = jQuery.sap.getUriParameters().get("responderOn") === "true";
// Start the mock server for the domain model
if (bIsMocked) {
this._startMockServer(sServiceUrl);
}
// Create and set domain model to the component
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, {json: true,loadMetadataAsync: true});
oModel.attachMetadataFailed(function(){
this.getEventBus().publish("Component", "MetadataFailed");
},this);
this.setModel(oModel);
// Set device model
var oDeviceModel = new sap.ui.model.json.JSONModel({
isTouch : sap.ui.Device.support.touch,
isNoTouch : !sap.ui.Device.support.touch,
isPhone : sap.ui.Device.system.phone,
isNoPhone : !sap.ui.Device.system.phone,
listMode : sap.ui.Device.system.phone ? "None" : "SingleSelectMaster",
listItemType : sap.ui.Device.system.phone ? "Active" : "Inactive"
});
oDeviceModel.setDefaultBindingMode("OneWay");
this.setModel(oDeviceModel, "device");
this.getRouter().initialize();
},
_startMockServer : function (sServiceUrl) {
jQuery.sap.require("sap.ui.core.util.MockServer");
var oMockServer = new sap.ui.core.util.MockServer({
rootUri: sServiceUrl
});
var iDelay = +(jQuery.sap.getUriParameters().get("responderDelay") || 0);
sap.ui.core.util.MockServer.config({
autoRespondAfter : iDelay
});
oMockServer.simulate("model/metadata.xml", "model/");
oMockServer.start();
sap.m.MessageToast.show("Running in demo mode with mock data.", {
duration: 4000
});
},
getEventBus : function () {
return sap.ui.getCore().getEventBus();
}
});
3.MyRouter.js
页面之间navigate调用。
jQuery.sap.require("sap.m.routing.RouteMatchedHandler");
jQuery.sap.require("sap.ui.core.routing.Router");
jQuery.sap.declare("ZTMP_MD.MyRouter");
sap.ui.core.routing.Router.extend("ZTMP_MD.MyRouter", {
constructor : function() {
sap.ui.core.routing.Router.apply(this, arguments);
this._oRouteMatchedHandler = new sap.m.routing.RouteMatchedHandler(this);
},
myNavBack : function(sRoute, mData) {
var oHistory = sap.ui.core.routing.History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
//The history contains a previous entry
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
var bReplace = true; // otherwise we go backwards with a forward history
this.navTo(sRoute, mData, bReplace);
}
},
/**
* Changes the view without changing the hash.
*
* @param {object} oOptions must have the following properties
* <ul>
* <li> currentView : the view you start the navigation from.</li>
* <li> targetViewName : the fully qualified name of the view you want to navigate to.</li>
* <li> targetViewType : the viewtype eg: XML</li>
* <li> isMaster : default is false, true if the view should be put in the master</li>
* <li> transition : default is "show" the navigation transition</li>
* <li> data : the data passed to the navContainers life cycle events</li>
* </ul>
* @public
*/
myNavToWithoutHash : function (oOptions) {
var oSplitApp = this._findSplitApp(oOptions.currentView);
// Load view, add it to the page aggregation, and navigate to it
var oView = this.getView(oOptions.targetViewName, oOptions.targetViewType);
oSplitApp.addPage(oView, oOptions.isMaster);
oSplitApp.to(oView.getId(), oOptions.transition || "show", oOptions.data);
},
backWithoutHash : function (oCurrentView, bIsMaster) {
var sBackMethod = bIsMaster ? "backMaster" : "backDetail";
this._findSplitApp(oCurrentView)[sBackMethod]();
},
destroy : function() {
sap.ui.core.routing.Router.prototype.destroy.apply(this, arguments);
this._oRouteMatchedHandler.destroy();
},
_findSplitApp : function(oControl) {
var sAncestorControlName = "idAppControl";
if (oControl instanceof sap.ui.core.mvc.View && oControl.byId(sAncestorControlName)) {
return oControl.byId(sAncestorControlName);
}
return oControl.getParent() ? this._findSplitApp(oControl.getParent(), sAncestorControlName) : null;
}
});
4. model
放置model的metadata信息。
5. view
主要工作区域,定义view以及controller,可以看到,在这个master detail模板中,App view用于定义split container,master view定义list显示的内容,detail用于显示master list中选中的记录的详细信息。NotFound view用于显示错误的链接信息。
6. i18n
用于globalization,翻译工作在此进行。
7. css
如果需要使用到自定义的css,则在此处定义,在index或者view中加载。
SAP一直在更新WebIDE的版本,所以,这些Template会随之更新。