【问题标题】:How can I use Typescript with SapUI5 resolving the two module systems如何使用 Typescript 和 SapUI5 解决两个模块系统
【发布时间】:2018-05-17 11:20:12
【问题描述】:

我正在尝试将 Typescript 与 SAPUI5 一起使用,我已经看到了几个创建 Typescript 类,然后将其传递给 SAPUI5 控制器中的 Controller.extend 的示例。

我遇到的问题是当我尝试在 Typescript 中使用模块时,例如“import * as $ from “jquery”。Typescript 为模块生成 define() 包装器,并注入 'require'、'export'和'jquery'。当我尝试加载它时,我得到'define not found',当我包含'requirejs'时,我得到'export not found'。

这是我得到的最接近的,但它使模块系统分开,并且需要大量的接口代码:

index.html:

<!DOCTYPE HTML>
<html>

<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Test App</title>

    <!--Loads from sapui5.hana.ondemand.com-->
    <script src="/resources/sap/ui/thirdparty/require.js"></script>

    <script src="/resources/sap-ui-core.js"
            data-sap-ui-theme='sap_bluecrystal'
            data-sap-ui-libs='sap.m,sap.ui.commons,sap.ui.table'
            data-sap-ui-bindingSyntax='complex'
            data-sap-ui-resourceroots='{"TestApp": "/testApp"}'>
    </script>

    <script>
        require(["/testApp/controller/tsclasses/Home.js"], function (contHome) {
            window.tsclasses = {
                controller: {
                    Home: contHome.default
                }
            };

            sap.ui.getCore().attachInit(function () {
                sap.m.Shell({
                    title: "Test App",
                    showLogout: true,
                    appWidthLimited: false,
                    app: new sap.ui.core.ComponentContainer({
                        height: "100%",
                        name: "TestApp"
                    })
                }).placeAt("content");
            });
        });
    </script>

</head>
<body id="content" style="margin: 0" class="sapUiBody">
</body>
</html>

组件.js

sap.ui.define(["sap/ui/core/UIComponent"], function (UIComponent) {
    "use strict";
    return UIComponent.extend("TestApp", {

        metadata: {
            rootView: "TestApp.view.App",
            routing: {
                config: {
                    routerClass: "sap.m.routing.Router",
                    viewPath: "TestApp.view",
                    controlId: "rootControl",
                    controlAggregation: "pages",
                    viewType: "XML"
                },
                routes: [
                    {
                        name: "home",
                        // empty hash - normally the start page
                        pattern: "",
                        target: "home"
                    }],
                targets: {
                    "home": {
                        viewName: "Home",
                        viewLevel: 0
                    }
                }
            }
        },

        init: function () {
            UIComponent.prototype.init.apply(this, arguments);

            var AppComponent = this;

            AppComponent.getRouter().initialize();
        }

    });
}, /* bExport= */ true);

Home.controller.js

sap.ui.define(
    ["sap/ui/core/mvc/Controller"],
    function (Controller) {

        "use strict";

        return Controller.extend("TestApp.controller.Home", new tsclasses.controller.Home());
    }
);

首页.ts

import * as $ from "jquery";
declare var sap: any;

namespace tsclasses.controller {
    export class Home extends sap.ui.core.mvc.Controller {
        public onInit(): void {
            alert('here');
            var x = $(window).width();
        }
    }
}

export default tsclasses.controller.Home;

App.view.xml

<View xmlns="sap.m">
    <App id="rootControl">
    </App>
</View>

Home.view.xml

<View
    xmlns="sap.m"
    controllerName="TestApp.controller.Home">

  <Page class="sapUiContentPadding"
        title="App Test Home">
    <content>

      <Text text="text" />

    </content>
  </Page>
</View>

这个解决方案对我来说非常值得,因为我真的很想使用类型检查和智能感知,但是我真的很想以某种方式让我的 Typescript 模块加载器和 SAPUI5 模块加载器共享状态等,以便它工作正确。

【问题讨论】:

  • 看起来 'require' 和 'exports' 是 AMD 模型系统中的特殊值。也许我应该配置我的 VS2017 项目以使用不同的模块系统。有人知道是哪一个吗?

标签: typescript sapui5


【解决方案1】:

我还没有找到合适的解决方案来解决我的问题,但我已经确定了我认为最简洁的解决方案,它总体上使用的文件更少。

由于 VS 2017 会自动检查引用类型,因此您无需导入目标模块,例如如果要对 jquery 进行类型检查,则不必 import * as $ from 'jquery'。不必导入模块意味着您可以在没有任何模块加载器或模块类型功能的情况下转换 Typescript。您还必须切换到 ES5 输出,因为 ES6 输出仍然使用 'exports' 变量输出一行。

我的测试文件现在如下所示:

index.html:

<!DOCTYPE HTML>
<html>

<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Test App</title>

    <script src="/resources/sap-ui-core.js"
            data-sap-ui-theme='sap_bluecrystal'
            data-sap-ui-libs='sap.m,sap.ui.commons,sap.ui.table'
            data-sap-ui-bindingSyntax='complex'
            data-sap-ui-resourceroots='{"TestApp": "/testApp"}'>
    </script>

    <script>
        sap.ui.getCore().attachInit(function () {
            sap.m.Shell({
                title: "Test App",
                showLogout: true,
                appWidthLimited: false,
                app: new sap.ui.core.ComponentContainer({
                    height: "100%",
                    name: "TestApp"
                })
            }).placeAt("content");
        });
    </script>

</head>
<body id="content" style="margin: 0" class="sapUiBody">
</body>
</html>

Component.js

sap.ui.define(["sap/ui/core/UIComponent"], function (UIComponent) {
    "use strict";
    return UIComponent.extend("TestApp", {

        metadata: {
            rootView: "TestApp.view.App",
            routing: {
                config: {
                    routerClass: "sap.m.routing.Router",
                    viewPath: "TestApp.view",
                    controlId: "rootControl",
                    controlAggregation: "pages",
                    viewType: "XML"
                },
                routes: [
                    {
                        name: "home",
                        // empty hash - normally the start page
                        pattern: "",
                        target: "home"
                    }],
                targets: {
                    "home": {
                        viewName: "Home",
                        viewLevel: 0
                    }
                }
            }
        },

        init: function () {
            UIComponent.prototype.init.apply(this, arguments);

            var AppComponent = this;

            AppComponent.getRouter().initialize();
        }

    });
}, /* bExport= */ true);

Home.controller.js

在 SAPUI5 的模型中,类型 'TestApp.controller.Home' 被导出到全局范围内,因此在定义替换它之后立即重新定义类型,这允许我们使用 Typescript 编写的类来定义 TestApp.controller.Home .此外,SAPUI5 可以将裸 Javascript 文件加载到全局范围内,而不会将它们作为模块,因此我们可以在此处加载所需的类 - 这两个技巧允许我们将所有内容很好地放入单个控制器文件中。

declare var sap: any;

sap.ui.define(
    ["sap/ui/core/mvc/Controller", "/TestApp/controller/tsclasses/DataClass"],
    function (Controller: any, jsDataClass: any) {

        "use strict";

        return Controller.extend("TestApp.controller.Home", {});
    }
);

namespace TestApp.controller {
    export class Home extends sap.ui.core.mvc.Controller {
        public onInit() {
            var data = new tsclasses.controller.DataClass();
            alert(data.message);
            alert('width = ' + $(window).width());
        }
    }
}

Home.ts - 已删除 - 不再需要

App.view.xml

<View xmlns="sap.m">
    <App id="rootControl">
    </App>
</View>

Home.view.xml

<View
    xmlns="sap.m"
    controllerName="TestApp.controller.Home">

  <Page class="sapUiContentPadding"
        title="App Test Home">
    <content>

      <Text text="text" />

    </content>
  </Page>
</View>

【讨论】:

    猜你喜欢
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 2017-04-23
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    相关资源
    最近更新 更多