如何理解 SAP UI5 的 sap.ui.define 函式

JerryWang_汪子熙 發表於 2021-10-11

Understanding sap.ui.define by Hello World

隨著 1.28 版本中 sap.ui.define 函式的引入,SAPUI5 引入了對非同步模組定義 (AMD) 的支援。AMD 是 Asynchronous Module Definition 的縮寫。

所謂模組(Module),即是可以在瀏覽器中載入和執行的 JavaScript 檔案。

非同步模組定義 (AMD) 是一種 JavaScript API,它指定了一種定義模組及其依賴項的方式,以便它們可以非同步載入而無需擔心載入順序。

下面我們通過一個具體的例子來講解 sap.ui.define 的工作原理。

Create an Application Project for SAPUI5

開啟 Eclipse 並轉到選單選項,檔案 -> 新建 -> 其他...。 在 New 視窗中,開啟節點 SAPUI5 Application Development 並選擇 Application Project 選項。 單擊下一步按鈕。

如何理解 SAP UI5 的 sap.ui.define 函式

為專案提供一個名稱。 我們稱之為 sapui5.amd.demo。 選擇庫 sap.m 並選中 Create an Initial View 選項。 單擊下一步按鈕。

如何理解 SAP UI5 的 sap.ui.define 函式

在下一個視窗中,為檢視提供一個名稱。 我們稱其為主要的。 選擇 Development Paradigm 作為 XML。 這將建立一個 XML 檢視。 單擊完成按鈕。

如何理解 SAP UI5 的 sap.ui.define 函式

建立好的專案具有如下的層級結構:
如何理解 SAP UI5 的 sap.ui.define 函式

Modify index.html

開啟 index.html 檔案並使用以下程式碼更新它。 Bootstrap 指令碼部分已被修改,以防止過早載入 sap.m 庫。 此外,出於類似原因,建立 sap.m.App 例項的自動生成程式碼已被註釋掉。 當 index.html 在瀏覽器中執行時,for 迴圈會列印出載入庫模組的初始列表。

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

<!-- 
    Replace this with the modified bootstrap section below        
<script 
    src="resources/sap-ui-core.js"
    id="sap-ui-bootstrap"
    data-sap-ui-libs="sap.m"
    data-sap-ui-theme="sap_bluecrystal">
</script>
-->

<!-- 
    Do not load the sap.m library right now. 
    We'll do it asynchronously in sap.ui.define 
-->
<script src="resources/sap-ui-core.js" id="sap-ui-bootstrap"
    data-sap-ui-theme="sap_bluecrystal">
    
</script>

<script>
    sap.ui.localResources("sapui5.amd.demo");
    
    /* 
     * Since we are not creating an instance of sap.m.App to
     * avoid the loading of sap.m at this stage, comment this out.
     */
    /*
    var app = new sap.m.App({initialPage:"idmain1"});
    var page = sap.ui.view({id:"idmain1", viewName:"sapui5.amd.demo.main", 
        type:sap.ui.core.mvc.ViewType.XML});
    app.addPage(page);
    app.placeAt("content");
    */     

    // Get reference to the Core object
    var oCore = sap.ui.getCore();

    // Place the XML view in the body of this page
    oCore.attachInit(function() {
        sap.ui.core.mvc.XMLView({
            viewName : "sapui5.amd.demo.main",
        }).placeAt("content");
    });

    // Set the log level to INFO
    jQuery.sap.log.setLevel(jQuery.sap.log.Level.INFO);

    // Print out the list of all currently loaded libraries
    jQuery.sap.log.info("--- Loaded Libraries in INDEX.HTML ---");
    var oLibMap = oCore.getLoadedLibraries();
    for ( var key in oLibMap) {
        jQuery.sap.log.info("Library name", key);
    }
</script>

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

Modify main.view.xml

開啟 main.view.xml 檔案並使用以下程式碼更新它。 它幾乎與 Eclipse 中自動生成的程式碼相同,只是新增了標題。

<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
        controllerName="sapui5.amd.demo.main" xmlns:html="http://www.w3.org/1999/xhtml">
    <Page title="Asynchronous Module Definition Demo">
        <content>                
        </content>
    </Page>        
</core:View>

Modify main.controller.js

控制器是 AMD 相關操作發生的地方。 開啟 main.controller.js 檔案並使用下面給出的程式碼更新它。 這裡要注意的重要變化是在第一行中,函式呼叫 sap.ui.controller () 已被註釋掉,以便為 AMD 函式 sap.ui.define () 讓路,它具有以下語法:

sap.ui.define(sModuleName?, aDependencies?, vFactory, bExport?)

(1) sModuleName 是一個可選引數,它是正在定義的模組的名稱。 如果省略,它將替換為用於請求模組的名稱。 所以,如果一個模組的名字比如說“LoginModule”沒有作為引數傳遞,它可以被請求為“sap/login/LoginMudule”,因為它儲存在一個檔案“sap/login/LoginModule.js”中。

(2) aDependencies 是作為依賴項的模組名稱的字串陣列。

這個陣列包含了在確定當前定義的模組的值之前需要載入的依賴模組。

(3) vFactory 是一個強制性的工廠函式,用於計算模組的值。

每個依賴模組名稱都作為引數傳遞給這個工廠函式,其順序與它們在字串陣列中指定的順序相同。

(4) bExport 是一個布林變數,保留供 SAP 使用。

在下面的示例中,沒有傳遞模組名稱。 並且依賴字串陣列 包含模組名稱 ["sap / ui / core / mvc / Controller", "sap / m / MessageToast"]。 然後將這些名稱作為引數(以相同的順序,即Controller、MessageToast)傳遞給工廠函式。

控制器的 onInit 生命週期方法中的程式碼列印出所有已載入庫的列表。

最後 onAfterRendering 函式使用 sap.m.MessageToast.show () 在螢幕上顯示一個簡短的 Hello World 訊息。

//sap.ui.controller("sapui5.amd.demo.main", {
sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast" ], function(Controller, MessageToast) {
    
    "use strict";
    
    return Controller.extend("sapui5.amd.demo.main", {    

/**
* Called when a controller is instantiated and its View controls (if available) are already created.
* Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
* @memberOf sapui5.amd.demo.main
*/
    onInit: function() {

        // Get reference to the Core object
        var oCore = sap.ui.getCore();
        // Print out the list of all currently loaded libraries
        jQuery.sap.log.info("--- Loaded Libraries in INIT of controller ---");        
        var oLibMap = oCore.getLoadedLibraries();
        for (var key in oLibMap) {
            jQuery.sap.log.info("Library name", key);
        }
        
    },

/**
* Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
* (NOT before the first rendering! onInit() is used for that one!).
* @memberOf sapui5.amd.demo.main
*/
//    onBeforeRendering: function() {
//
//    },

/**
* Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
* This hook is the same one that SAPUI5 controls get after being rendered.
* @memberOf sapui5.amd.demo.main
*/
    onAfterRendering: function() {

        MessageToast.show("Hello World!");
    },

/**
* Called when the Controller is destroyed. Use this one to free resources and finalize activities.
* @memberOf sapui5.amd.demo.main
* 
*/
//    onExit: function() {
//
//    }
    
    });

});

注意:“use strict”這個文字表示式是由 JavaScript 1.8.5 (ECMAScript 5) 引入的。 它告訴瀏覽器以所謂的“嚴格模式”執行程式碼。 嚴格模式有助於在開發時的早期狀態檢測潛在的編碼問題,這意味著,例如,它確保在使用變數之前宣告變數。 因此,它有助於防止常見的 JavaScript 陷阱,因此使用嚴格模式是一個很好的做法。

Deploy and Run Application

啟動伺服器並部署應用程式。 開啟一個新的瀏覽器視窗(此示例使用 Chrome 瀏覽器)並開啟 Chrome 開發者工具。

如何理解 SAP UI5 的 sap.ui.define 函式

在瀏覽器中開啟如下網址 http://localhost:8180/sapui5....
請根據您的伺服器配置使用埠號。 載入 index.html 會簡要顯示 Hello World 訊息,並將在開發人員工具控制檯中列印日誌。

從列印的 log 資訊可以看到: sap.m 模組直到將模組依賴列表傳遞給 sap.ui.define之後才載入。

如何理解 SAP UI5 的 sap.ui.define 函式

更多Jerry的原創文章,盡在:"汪子熙":
如何理解 SAP UI5 的 sap.ui.define 函式