2

给定一个 ES 模块dictionaryAPI.mjs

export const DICTIONARY_API = Object.freeze({
    someKey: "someValue"
});

我想将它导入我的 UI5 控制器。据我了解,UI5 不支持.mjs扩展,因此我将扩展从 更改.mjs.js. 然后,我尝试将它添加到 UI5 控制器中,准确地说,是实用程序控制器ControllerUtilities.js

sap.ui.define([
    "com/myApp/dictionaryAPI"
    ],
    (dictionaryAPI) => ({…}));

当我运行应用程序时,我收到一个错误:

'com/myApp/controller/ControllerUtilities.js': Unexpected token 'export'

sap-ui-core.js:53 Uncaught (in promise) ModuleError: Failed to resolve dependencies of 'com/myApp/controller/Login.controller.js'
 -> 'com/myApp/controller/BaseController.js'
  -> 'com/myApp/controller/ControllerUtilities.js': Unexpected token 'export'
    at p1 (https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:53:213)
    at j1.failWith (https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:40:43)
    at https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:65:1556
Caused by: SyntaxError: Unexpected token 'export'

看起来,UI5 无法识别exportES 模块中的语句。

是否有任何选项可以将 ES 模块导入 UI5 控制器?

使用版本:OpenUI5 1.96.0

4

3 回答 3

5

UI5 默认使用 UMD 导入语法 ( sap.ui.define, sap.ui.require)。要让它理解其他模块类型,您必须“欺骗”它认为该模块是 UMD。

这可以通过使用ui5 cli来完成。

您必须构建一个正确的文件夹结构(package.json、ui5.yaml、webapp 文件夹),并且在 ui5.yaml 文件中您可以为相应的 ES 模块定义项目 shim 。

一个便宜又实用的替代方法是通过标签包含 ES 模块 <script src="path/to/module" type="module">,但我不知道有人会推荐这个,因为这不允许捆绑。

于 2021-10-17T07:50:07.710 回答
1

最好的解决方案是创建一个fmi21提到的新模块。

您的 API 可能看起来像这样,它只返回一个带有DICTIONARY_API. 因此,您还可以向 API 添加更多属性。

sap.ui.define([], function () {
"use strict";

    return {
        DICTIONARY_API : Object.freeze({
            someKey: "someValue"
        })
    }
});

然后你可以像在你的ControllerUtilities.js

您还可以通过以下方式将 JSON 文件直接加载到模型中manifest.json

{
  "sap.ui5": {
    "models": {
      "YOURMODELNAME": {
        "type": "sap.ui.model.json.JSONModel",
        "uri": "PATH TO JSON"
      }
    }
  }
}
于 2021-10-31T10:22:19.833 回答
0

如果它是一个模型,需要在系统范围内访问,最简单的方法是manifest.jsonsap.ui5/下声明它models

"dictionaryAPI": {
    "type": "sap.ui.model.json.JSONModel",
    "uri": "model/dictionaries/api.json"
},

或者,可以从根视图 ( rootViewin manifest.json) 的控制器加载模型,这使得模型在整个应用程序运行期间可用于每个视图:

async loadDictionaryData(dataSource, modelName) {

    const dictionaryModel = new JSONModel();

    await dictionaryModel.loadData(dataSource);

    this.getView().setModel(dictionaryModel, modelName);

}

无需关心数据同步/异步加载、重用、ESM/UMD 等。

于 2021-10-31T10:55:27.447 回答