如何在SapUI5中使用Typescript解析两个模块系统

时间:2018-05-17 11:20:12

标签: typescript sapui5

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

我遇到的问题是当我尝试使用Typescript中的模块时,例如" import * as $ from the#34; jquery"。 Typescript为模块生成define()包装器,并注入' require',' export'和' jquery'。当我尝试加载它时,我得到了“未找到”的定义'当我包含' requirejs'时,我发现未找到导出'。

这是我最接近的,但它使模块系统保持独立,并且需要大量的接口代码:

的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>

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

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

        "use strict";

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

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模块加载器共享状态等等它运作正常。

1 个答案:

答案 0 :(得分:0)

我无法找到解决问题的正确方法,但我已经确定了我认为整体使用较少文件的最整洁解决方案。

由于VS 2017类型会自动检查引用的类型,因此您无需导入目标模块,例如如果你想要查询jquery,你不必从'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'被导出到全局范围,因此在define替换之后立即重新定义类型,这允许我们使用在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>