如何通过 ID 访问 XML 片段中的元素

问题描述 投票:0回答:3

我正在开发 SAPUI5 应用程序。我有一个 XML 视图,其中包含一个 XML Fragment 和一个要保存的按钮。

该片段包含一些控件,例如下拉列表、文本字段和表格。 当我按下保存按钮时,我需要获取表中的所有行并调用 OData 更新服务。

问题出在视图控制器中的

onSave
方法中。使用表 ID 访问表时出现错误。谁能帮助我并建议我如何通过控制器中的 ID 访问片段中使用的控件?

这是代码片段:

查看:

<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" xmlns:form="sap.ui.layout.form" xmlns="sap.m">
    <Page>
        ...
        <form:SimpleForm>
            <core:Fragment id ="fr1" fragmentName="first" type="XML" />
            <Button id="id1" press="onSave" />
        </form:SimpleForm>
    </Page>
</mvc:View>

片段定义:

<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
    <Table id="tab1" mode="MultiSelect">
        ...
    </Table>
</core:FragmentDefinition>

控制器:

sap.ui.controller("view", {
    onSave: function() {
        //var tab = this.getView().byId("tab1"); // Not working
        var tab  = sap.ui.getCore().byId("tab1"); // Not working
    },
    // ...
});
sapui5 sap-fiori
3个回答
40
投票

访问片段内的控件取决于片段的创建方式。以下是场景列表,其中包含用于获取控件引用的相应 API。

给出:

  • this
    作为当前控制器实例的引用
  • Fragment
    需要
    sap/ui/core/Fragment
  • <MyControl id="controlId"/>
    在片段定义中

可供选择的API


👉
this.byId("controlId");

...如果片段是使用视图 ID(推荐)直接或间接创建的:

  • this.loadFragment({ name: "..." }); // id: view ID given by default, API since 1.93
    
  • <!-- In the view embedding the fragment declaratively: -->
    <core:Fragment fragmentName="..." type="XML"/><!-- id = view ID given by default -->
    
  • Fragment.load({ // API since 1.58
      id: this.getView().getId(),
      name: "...",
      controller: this,
    });
    
  • sap.ui.xmlfragment(this.getView().getId(), "...", this); // Deprecated

    生成的全局 ID:

    "componentId---viewId--controlId"
    *


👉
this.byId(Fragment.createId("fragmentId", "controlId"));

...如果给定片段 ID 视图 ID 组合:

  • this.loadFragment({ id: this.createId("fragmentId"), name: "..." });
    
  • <core:Fragment id="fragmentId" fragmentName="..." type="XML"/>
    
  • Fragment.load({
      id: this.createId("fragmentId"),
      name: "...",
      controller: this,
    });
    
  • sap.ui.xmlfragment(this.createId("fragmentId"), "...", this); // Deprecated

    生成的全局 ID:

    "componentId---viewId--fragmentId--controlId"
    *


👉
Fragment.byId("fragmentId", "controlId");

...如果只给出了片段 ID 而没有与视图 ID 相结合:

  • this.loadFragment({
      id: "fragmentId",
      name: "...",
      autoPrefixId: false, // Explicitly disabled view ID as prefix
    });
    
  • Fragment.load({
      id: "fragmentId",
      name: "...",
      controller: this,
    });
    
  • sap.ui.xmlfragment("fragmentId", "...", this); // Deprecated

    生成的全局 ID:

    "fragmentId--controlId"
    *


👉
Element.getElementById("controlId") // since 1.119

Element.registry.get("controlId") // since 1.67

(原

sap.ui.getCore().byId("controlId")

...如果没有给出前缀 ID。 不推荐以下设置,因为片段定义中的所有控件 ID 将在没有任何前缀的情况下全局注册。无法保证 ID 的唯一性!

  • this.loadFragment({ name: "...", autoPrefixId: false }); // Not recommended if no id
  • Fragment.load({ name: "...", controller: this }); // Not recommended
  • sap.ui.xmlfragment("demo.view.MyFragment", this); // Deprecated

    生成的全局 ID:

    "controlId"


* 不要依赖生成的全局 ID,例如,在应用程序中手动连接 ID 部分。始终使用上面提到的专用 API,例如

byId
createId
。请参阅稳定 ID:您需要了解的一切


支持模型优先方法而不是
byId

不要直接访问片段控件,而是考虑通过数据绑定操作 UI。模型中的更改将自动反映在 UI 中,并且,如果启用双向绑定,来自 UI 的用户输入将直接存储在模型中。


SAP Fiori 元素 指南

开发 Fiori 元素扩展时,请确保遵守记录的 兼容性指南,尤其是关于

byId

[...] 不要访问或操纵 SAP Fiori 元素的内部编码。
[...] 不得访问任何在您的视图扩展中定义的 UI 元素。

⚠注意
如果您不遵守此指南,您的应用程序可能无法与未来的 SAPUI5 版本一起使用,因为 SAP Fiori 元素可能会将控件交换为具有不同 API 的新元素。


27
投票

查看 GitHub 上的 OpenUI5 代码,如果

<Fragment/>
本身没有 具有显式 ID,则 Fragment 似乎会将本地 ID 生成委托给包含视图。

因此,一旦您从

this.getView().byId("tab1")

 元素中删除 
id="fr1"
 属性,您的代码 
<Fragment/>
 就应该可以正常工作。

使用显式 ID 时,有一个

static Fragment.byId

 方法来检索控件。我想你必须像这样使用它:

// Fragment required from "sap/ui/core/Fragment" var fragmentId = this.getView().createId("fr1"); var tab = Fragment.byId(fragmentId, "tab1");
    

2
投票
为了使其在没有显式片段 ID 和静态 Fragment.byId() 的情况下工作,我使用了以下代码片段:

var prefix = this.getView().createId("").replace("--", ""); var fragment = sap.ui.xmlfragment(prefix, "-- XML fragment name --", this);

在此之后,您可以像使用任何其他控件一样使用 this.getView().byId("tab1") 。

© www.soinside.com 2019 - 2024. All rights reserved.