WebIDE生成的代码模板分析

本文深入分析了SAP WebIDE生成的Master-Detail应用模板,包括index.html的加载机制、Component.js中的路由配置与模型绑定、MyRouter.js中的导航逻辑及视图的组织方式。适用于希望了解该模板内部实现细节的开发者。

前面介绍了如何把代码转移到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会随之更新。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值