SAPUI5 (20) - 在 Component 中封裝啟動代碼

本篇對上篇的代碼進行重構。在 SAP Fiori 中 app 并不是通過 index.html 啟動的,而是通過 Component 啟動袍嬉,因為 SAP Launchpad 包含多個 app。所以我們學習 OpenUI5 也應該熟悉這種模式。Component 是 OpenUI5 的一種組織代碼結構的方式音诈。

第一次重構幻碱,代碼的項目文件結構如下:

在 Component 中編寫啟動代碼

我們先來看 Component.js 文件的內容:

sap.ui.define([
        "sap/ui/core/UIComponent",
        "sap/ui/model/json/JSONModel"
    ], 
        
    function(UIComponent, JSONModel){
        return UIComponent.extend("webapp.Component", {         
            createContent: function() {
                UIComponent.prototype.createContent.apply(this, arguments);
                
                // load application data
                var oModel = new sap.ui.model.json.JSONModel();
                oModel.loadData("webapp/service/data.json");
                this.setModel(oModel);
                
                // app view(root view)
                var oAppView = sap.ui.view("appView", {
                    type: sap.ui.core.mvc.ViewType.XML,
                    viewName: "webapp.view.App"
                })
                
                oApp = oAppView.byId("app");
                return oAppView;                
            }
        });
    }

);

代碼說明

  • Component.js 這個文件名不能更改,但位置可以設定细溅。在Component.js文件中褥傍,webapp.Component 類從sap.ui.core.UIComponent 類擴展,并且改寫了 createContent 方法喇聊。

  • 接下來的代碼在之前的項目代碼 index.html 中常見恍风,完成加載 Application data,設置 webapp.component 這個組件的 Model:

// load application data
var oModel = new sap.ui.model.json.JSONModel();
oModel.loadData("webapp/service/data.json");
this.setModel(oModel);
  • 定義一個 Root View誓篱,或者叫做 Application View:
var oAppView = sap.ui.view("appView", {
    type: sap.ui.core.mvc.ViewType.XML,
    viewName: "webapp.view.App"
})
  • 定義一個全局變量 oApp :
oApp = oAppView.byId("app");
return oAppView;           

之前代碼中朋贬, oApp 通過創(chuàng)建 new sap.m.App() 對象實例來實現,本次的示例代碼把它放在 App View 中進行申明燕鸽,一會我們再來看 App View 的代碼兄世。由于在 App View 中申明 app,所以在這里通過oAppView.byId("app")來獲取全局的 Application 對象啊研。

簡化 index.html

重構后 sap.m.App 在 App View 中聲明御滩,Application Data 和 Root View 的代碼移到 Component.js 文件中,所以 index.html 中的代碼大大減少党远,只需要定義一個 sap.ui.core.ComponentContainer 對象削解,在 ComponentContainer 中包括剛剛定義的 Component 對象。index.html 代碼如下:

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>

        <script src="resources/sap-ui-core.js"
                id="sap-ui-bootstrap"
                data-sap-ui-libs="sap.m"
                data-sap-ui-preload="async"
                data-sap-ui-xx-bindingSyntax="complex"
                data-sap-ui-resourceroots = '{"webapp": "./webapp/"}'
                data-sap-ui-theme="sap_bluecrystal">
        </script>

        <script>
        
            var oApp;
            
            sap.ui.getCore().attachInit(function(){
                sap.ui.require([
                        "sap/ui/core/ComponentContainer",
                        "webapp/Component"
                    ], 
                    
                    function(ComponentContainer, Component){
                        new ComponentContainer({
                            height: "100%",
                            component: new Component({
                                id: "mvcAppComponent"
                            })
                        }).placeAt("content");
                    }
                );
            });
            
        </script>

    </head>
    <body class="sapUiBody" role="application">
        <div id="content" class="sapUiResponsiveMargin"></div>
    </body>
</html>

ComponentContainer 實例化的 component 參數指定容器所包含的 Component 沟娱,也可也使用 name 參數氛驮,name 根據文件的相對位置來指定所包含的 Component 對象。比如:name: "webapp"济似,index.html` 中

data-sap-ui-resourceroots = '{"webapp": "./webapp/"}

指定 webapp 為當前文件夾下的 webapp 文件夾矫废,OpenUI5 就在這個文件夾下查找 Component.js 文件。

App view 內嵌 Master View 和 Detail View

之前是在 index.html 中實例化 Master View 和 Detail View砰蠢,并且將 View 包含在 app 的 pages 中蓖扑。代碼模式如下:

var masterView = sap.ui.xmlview("masterView", {...});
var detailView= sap.ui.xmlview("detailView", {...});

現在變?yōu)?Master View 和 Detail View 在 App.view.xml文件中申明:

<core:View xmlns:core="sap.ui.core" 
           xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
        xmlns:html="http://www.w3.org/1999/xhtml">
        
    <App id="app">
        <pages>
            <mvc:XMLView id="masterView" viewName="webapp.view.Master" />
            <mvc:XMLView id="detailView" viewName="webapp.view.Detail" />
        </pages>
    </App>
    
</core:View>

這種 View 中內嵌其它 View ,對后面通過代碼獲取 View 的 id 有影響台舱,OpenUI5 在View 的 id 前自動加上父 View 的 id律杠。比如 Master View 的id變成appView--masterView,Detail View 的 id 變?yōu)?appView--detailView竞惋。appView是 在 Component 中定義Root View時指定的 id柜去。在 Controller 中根據 View 的 id 導航的時候,需要用到這些 id拆宛。

Master Controller 和 Detail Controller 的代碼重構

Master View 和 Detail View 的代碼沒有變化嗓奢,Detail Controller 的代碼也沒有變化。Master Controller 因為需要能從 Master View 跳轉到 Detail View浑厚,并且在跳轉的時候用到 View 的 id蔓罚,所以代碼中 pageId 的代碼有變化:

sap.ui.define([
        "sap/ui/core/mvc/Controller"
    ],      
        
    function(Controller){
        "use strict";
        
         return Controller.extend("webapp.controller.Master", {
            onListPress: function(oEvent){
                // 跳轉到detail view
                var sPageId = oApp.getPages()[1].getId();
                oApp.to(sPageId);
                
                // 設置detail page的bindingContext
                var oContext = oEvent.getSource().getBindingContext();
                var oDetailPage = oApp.getPage(sPageId);
                oDetailPage.setBindingContext(oContext);
            }
         });    
    }
);

我們使用相對引用的方式椿肩,getPages() 獲取 app 的頁面,然后通過oApp.getPages()[1].getId()獲取 Detail Page的 id 豺谈。

在 Component 中實現相關配置

很多參數都可以配置在 Component 中郑象,我們將 Root View 和 Service URL 配置在 Component 的 metadata 中。metadata 也可以放到專門的配置文件中茬末, 這個配置 OpenUI5 叫 Application descriptor厂榛。

sap.ui.define([
        "sap/ui/core/UIComponent",
        "sap/ui/model/json/JSONModel"
    ], 
        
    function(UIComponent, JSONModel){
        return UIComponent.extend("webapp.Component", { 
            // meta-data
            metadata: {
                "rootView": "webapp.view.App",
                "config": {
                    "serviceUrl": "webapp/service/data.json"
                }
            },
            
            createContent: function() {
                // application data
                var oModel = new JSONModel(this.getMetadata().getConfig().serviceUrl);
                this.setModel(oModel);
                
                // root view
                var oRootView = UIComponent.prototype.createContent.apply(this, arguments);
                
                // application
                oApp = oRootView.byId("app");
                
                return oRootView;               
            }
        });
    }

);

代碼說明:

  • Component metadata 配置部分的 rootView,表示程序啟動時的第一個View丽惭。代碼中使用下面的語句獲取击奶。
var oRootView = UIComponent.prototype.createContent.apply(this, arguments);
  • json 數據在 metadata 配置的 config->serviceUrl 中,然后代碼中使用下面的語句獲仍鹛汀:
var oModel = new JSONModel(this.getMetadata().getConfig().serviceUrl);

index.html 添加 Shell 組件

為了更加美觀柜砾,一般 OpenUI5 的 App 都是放置在sap.m.Shell中,這樣换衬,頁面兩邊都有預留空間痰驱,App 位于中間,類似一個信封瞳浦。不錯担映,OpenUI5 就是將有 Shell 的頁面叫 letterboxing - 信封。

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>

        <script src="resources/sap-ui-core.js"
                id="sap-ui-bootstrap"
                data-sap-ui-libs="sap.m"
                data-sap-ui-preload="async"
                data-sap-ui-xx-bindingSyntax="complex"
                data-sap-ui-resourceroots = '{"webapp": "./webapp/"}'
                data-sap-ui-theme="sap_bluecrystal">
        </script>

        <script>
        
            var oApp;
            
            sap.ui.getCore().attachInit(function(){
                sap.ui.require([
                        "sap/m/Shell",
                        "sap/ui/core/ComponentContainer",
                        "webapp/Component"
                    ], 
                    
                    function(Shell, ComponentContainer, Component){
                        new Shell({
                            app: new ComponentContainer({
                                    height: "100%",
                                    component: new Component({
                                        id: "mvcAppComponent"
                                    })
                                })
                        }).placeAt("content");
                    }
                );
            });
            
        </script>

    </head>
    <body class="sapUiBody" role="application">
        <div id="content" class="sapUiResponsiveMargin"></div>
    </body>
</html>

頁面效果:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末叫潦,一起剝皮案震驚了整個濱河市蝇完,隨后出現的幾起案子,更是在濱河造成了極大的恐慌矗蕊,老刑警劉巖短蜕,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異傻咖,居然都是意外死亡忿危,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門没龙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缎玫,你說我怎么就攤上這事硬纤。” “怎么了赃磨?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵筝家,是天一觀的道長。 經常有香客問我邻辉,道長溪王,這世上最難降的妖魔是什么腮鞍? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮莹菱,結果婚禮上移国,老公的妹妹穿的比我還像新娘。我一直安慰自己道伟,他們只是感情好迹缀,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜜徽,像睡著了一般祝懂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拘鞋,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天砚蓬,我揣著相機與錄音,去河邊找鬼盆色。 笑死灰蛙,一個胖子當著我的面吹牛,可吹牛的內容都是我干的傅事。 我是一名探鬼主播缕允,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蹭越!你這毒婦竟也來了障本?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤响鹃,失蹤者是張志新(化名)和其女友劉穎驾霜,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體买置,經...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡粪糙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了忿项。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓉冈。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖轩触,靈堂內的尸體忽然破棺而出寞酿,到底是詐尸還是另有隱情,我是刑警寧澤脱柱,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布伐弹,位于F島的核電站,受9級特大地震影響榨为,放射性物質發(fā)生泄漏惨好。R本人自食惡果不足惜煌茴,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望日川。 院中可真熱鬧蔓腐,春花似錦、人聲如沸逗鸣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撒璧。三九已至透葛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卿樱,已是汗流浹背僚害。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留繁调,地道東北人萨蚕。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像蹄胰,于是被迫代替她去往敵國和親岳遥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評論 25 707
  • 前面我們實現了基于組件的多頁面程序裕寨,這個程序還有兩個主要的缺點: 1)存在全局變量oApp (sap.m.App)...
    Stone0823閱讀 3,260評論 0 8
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理浩蓉,服務發(fā)現,斷路器宾袜,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 白澍庆猫,你知道嗎……你的粉絲都是傻樹芽认轨,她們用盡了所有力氣來愛你,用盡所有力量把你留在我們的世界里月培。就那么幾百號人...
    白澍閱讀 332評論 0 3
  • 1 第一次進咱班教室時在班門口愣了幾秒嘁字,因為報道比較晚,班里已經擠滿人而且同學們都找到了各自的座位杉畜,班...
    心禾醬閱讀 152評論 0 0