SAPUI5基础知识20 - 对话框和碎片(Dialogs and Fragments)

1. 背景

在 SAPUI5 中,Fragments 是一种轻量级的 UI 组件,类似于视图(Views),但它们没有自己的控制器(Controller)。Fragments 通常用于定义可以在多个视图中重用的 UI 片段,从而提高代码的可重用性和模块化程度。

Fragment技术应用场景如下:

  • 代码重用:将常用的 UI 片段(如对话框、表单、工具栏等)定义为 Fragments,以便在多个视图中重用。
  • 模块化开发:将复杂视图分解为多个小的、可重用的 Fragments,提高代码的可维护性。
  • 动态加载:根据用户操作或其他条件动态加载 Fragments,提高应用程序的灵活性。

注1:由于 Fragments 没有自己的控制器,它们会使用嵌入它们的视图的控制器。

注2: Fragments 是一段独立的 UI 代码,可以用 XML、HTML、JSON 或 JavaScript 编写,在SAPUI5中推荐的方式是使用XML。格式要求:以.fragment.xml结尾,例如:FragmentName.fragment.xml。碎片文件的位置应放在视图view文件夹下。

2. 示例

假设我们有一个对话框 DialogFragment,需要在多个视图中使用。

2.1 创建 Fragment

DialogFragment.fragment.xml

xml 复制代码
<core:FragmentDefinition
    xmlns="sap.m"
    xmlns:core="sap.ui.core">
    <Dialog id="myDialog" title="My Dialog">
        <content>
            <VBox>
                <Text text="This is a dialog fragment"/>
                <Input placeholder="Enter something"/>
            </VBox>
        </content>
        <buttons>
            <Button text="OK" press="onDialogOk"/>
            <Button text="Cancel" press="onDialogCancel"/>
        </buttons>
    </Dialog>
</core:FragmentDefinition>

2.2 在视图中使用 Fragment

MainView.view.xml

xml 复制代码
<mvc:View
    controllerName="myApp.controller.MainView"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m">
    <Page>
        <content>
            <Button text="Open Dialog" press="onOpenDialog"/>
        </content>
    </Page>
</mvc:View>

MainView.controller.js

js 复制代码
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/Fragment"
], function (Controller, Fragment) {
    "use strict";
    return Controller.extend("myApp.controller.MainView", {
        onOpenDialog: function () {
            var oView = this.getView();

            // Check if the fragment is already created
            if (!this.byId("myDialog")) {
                // Load the fragment asynchronously
                Fragment.load({
                    id: oView.getId(),
                    name: "myApp.view.DialogFragment",
                    controller: this
                }).then(function (oDialog) {
                    // Connect dialog to the root view of this component (models, lifecycle)
                    oView.addDependent(oDialog);
                    oDialog.open();
                });
            } else {
                this.byId("myDialog").open();
            }
        },

        onDialogOk: function () {
            this.byId("myDialog").close();
        },

        onDialogCancel: function () {
            this.byId("myDialog").close();
        }
    });
});

3.练习

在前序练习的基础上,让我们为应用程序增加一个对话框,对话框相对特殊,因为它会在常规应用程序内容的顶部弹出,因此并不属于某个特定视图。

这意味着我们需要在控制器的某个位置,完成对话框的实例化。但由于我们想使用声明的方式创建控件,并希望保持可复用性和灵活性,我们将使用fragment技术来创建一个包含对话框的XML碎片。这样,对话框就可以在应用程序的多个视图中使用。

3.1 创建包含对话框的碎片

让我们在视图文件下,新建HelloDialog.fragment.xml碎片文件,在此文件中用声明的方式定义对话框<Dialog>控件。

碎片资源库位于sap.ui.core的命名空间中,我们在FragmentDefinition标签内部为它添加了一个xml命名空间。

定义Fragment的语法与视图类似,但由于片段没有控制器,因此无需定义该属性。

另外,碎片不在应用程序的DOM树中留下任何痕迹,也没有片段本身的控制实例(只有包含的控件)。 它只是一组可重用控件的容器

HelloDialog.fragment.xml碎片文件中的代码如下:

xml 复制代码
<core:FragmentDefinition 
    xmlns="sap.m"
    xmlns:core="sap.ui.core" >
    <Dialog
        id="helloDialog"
        title="Hello {/recipient/name}"
    />
</core:FragmentDefinition>

3.2 在主视图上新增按钮

接下来,让我们在HelloPanel.view.xml视图中添加了一个新按钮<Button>来打开对话框,并指定事件处理函数press=".onOpenDialog"。与此同时,让我们为此按钮控件设置一个id="helloDialogButton"

将关键控件的唯一ID设置为helloWorldButton是一个好习惯,这样可以方便识别。如果未指定id属性,则OpenUI5运行时会为控件生成唯一但易变的ID,例如"__button23"。在浏览器中检查应用程序的DOM元素,就可以看到差别。

改动后的HelloPanel.view.xml视图文件内容如下:

xml 复制代码
<mvc:View
    controllerName="zsapui5.test.controller.HelloPanel"
    xmlns="sap.m"
    xmlns:mvc="sap.ui.core.mvc"
>
    <Panel
        headerText="{i18n>helloPanelTitle}"
        class="sapUiResponsiveMargin"
        width="auto"
    >
        <content>
            <Button
                id="helloDialogButton"
                text="{i18n>openDialogButtonText}"
                press=".onOpenDialog"
                class="sapUiSmallMarginEnd"
            />
            <Button
                text="{i18n>showHelloButtonText}"
                press=".onShowHello"
                class="myCustomButton"
            />
            <Input
                value="{/recipient/name}"
                valueLiveUpdate="true"
                width="60%"
            />
            <FormattedText
                htmlText="Hello {/recipient/name}"
                class="sapUiSmallMargin sapThemeHighligh-asColor myCustomText"
            />
        </content>
    </Panel>
</mvc:View>

3.3 实现按钮的事件响应

最后,让我们在控制器文件中,实现按钮的事件响应程序。

新增方法onOpenDialogHelloPanel.controller.js中。如果片段中的对话框尚不存在,通过调用控制器模块的loadFragment API来实例化该片段。该方法返回一个Promise对象,一旦片段被异步加载完成,该Promise对象会被解析。

改动后的HelloPanel.controller.js文件内容如下:

js 复制代码
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/m/MessageToast"
], function (Controller, MessageToast) {
    "use strict";

    return Controller.extend("zsapui5.test.controller.HelloPanel", {
        onShowHello: function () {
           // read msg from i18n model
           const oBundle = this.getView().getModel("i18n").getResourceBundle();
           const sRecipient = this.getView().getModel().getProperty("/recipient/name");
           const sMsg = oBundle.getText("helloMsg", [sRecipient]);

           // show message
            MessageToast.show(sMsg);
        },

        onOpenDialog: function () {
            // create dialog lazily 
            if (!this.pDialog) {
                this.pDialog = this.loadFragment({
                    name: "zsapui5.test.view.HelloDialog"
                });

                this.pDialog.then(function (oDialog) {
                    oDialog.open();
                });
            }
        }
    });
});

3.4 增强i18n

别忘记为新增button的描述维护对应的i18n资源文件。

改动后的i18n.properties文件如下:

js 复制代码
# App Descriptor
appTitle=Hello World
appDescription=A simple app that explains the most important concepts of SAPUI5

# Hello Panel
showHelloButtonText=Say Hello
helloMsg=Hello {0}

homePageTitle=homePageTitle
helloPanelTitle=PanelTitle
openDialogButtonText=Say Hello With Dialog

3.5 运行程序

运行改动后的程序,我们可以看到新增的Say Hello With Button按钮。点击按钮后,会在弹出的窗口中显示Hello World。

目前的这个应用程序还是有些小问题,可见,弹出窗口是无法关闭的。在下一篇博客中,让我们进一步增强Fragment的回调函数,来实现弹出窗口的关闭。

4. 小结

本文介绍了SAPUI5中对话框和碎片的概念,并通过示例展示了其具体用法。

相关推荐
山茶花开时。7 天前
[SAP ABAP] 序列化与反序列化
开发语言·sap·abap
左甜甜9 天前
SAP MMPV报错MMPV_DATE_CHECK
sap
SAP女战士11 天前
【ABAP SAP】开发-BUG修补记录_采购申请打印时品名规格品牌为空
运维·数据库·bug·sap·abap开发
Cindy的SAP加油站13 天前
SAP Ariba_Order Fulfillment Status
sap·sap ariba
SAP学习成长之路14 天前
ADBC 查询语法介绍:EXECUTE_QUERY
java·服务器·开发语言·数据库·sap·abap·零售
需己以听的以听16 天前
4.模块化技术之子程序
sap·gui·abap·模块化·改行学it·子程序
syounger16 天前
近四分之一SAP ECC用户对未来规划尚不明朗
sap
SAP学习成长之路21 天前
SAP HANA 上进行 ABAP 开发:简介
开发语言·数据结构·数据库·sap·abap·代码规范
阿达_优阅达24 天前
利用 Xtract Universal,将 SAP 数据高效迁移至 Amazon S3 或 Redshift
数据库·sap·企业数字化转型·theobald sap·redshift
左甜甜25 天前
ABAP OOALV模板
sap·abap·alv