【问题标题】:OData Tree binding with filters in a fragmentOData 树与片段中的过滤器绑定
【发布时间】:2021-02-16 12:32:56
【问题描述】:

我在使用oModel.read() 启动 SAPUI5 应用程序时从 OData V2 服务读取数据。数据已从后端正确加载到 ODataModel。稍后我想在片段中使用我的一个实体(价值帮助)。

作为在片段中显示数据的控件是sap.m.Tree 控件。我不能使用本地 JSONModel 将数据绑定到片段,但必须坚持使用 ODataModel。

如何进行绑定以使数据显示在我的片段中?

这里是oModel.read

oModel.read("/CategoriesSet", {
  filters: aFilters,
  success: function(oResult) {
    // ...
  },
});

在值帮助中,片段被调用:

onCatValueHelp: function(oEvent){
  if (!this._oDialog) {
    this._oDialog = sap.ui.xmlfragment("<XXXXX>.view.Categories", this);
    this.getView().addDependent(this._oDialog);
  }
  this._oDialog.open();
},

这是片段:

<Tree id="CatTree" mode="MultiSelect"
  items="{
    path: '?????',
    parameters: {
      countMode: 'Inline',
      operationMode: 'Client',
      numberOfExpandedLevels: 0
    }
  }">
  <StandardTreeItem title="{CatName}" tooltip="{CatID}" />
</Tree>

如果我使用'/CategoriesSet' 作为路径,那么我会将数据加载到片段中,但随后会再次从后端获取数据,但没有过滤器。而且由于后端调用的性能不是很好,我宁愿使用之前oModel.read()的模型中已经存在的数据。

【问题讨论】:

  • 问题更深,因为您希望避免检索所有 CategoriesSet 实体。但是使用operationMode: 'Client',首先获取所有实体,然后过滤器将应用于客户端,即使过滤器是在树绑定构造函数中定义的。根据文档:>如果使用OperationMode.Client,则请求没有过滤器的完整集合;过滤器应用于客户端。
  • 您的后端是否支持 > 预过滤树并[...] 响应完整的树层次结构,包括所有内部节点?然后您可以将useServersideApplicationFilters: true 添加到parameters(但没有operationMode: 'Client'!)以避免获取所有实体。只有这样$filter 查询才会添加到 API 引用的请求 URL。
  • (个人意见..) 我会重新考虑是否绝对需要在树中显示类别。对于前端和后端开发人员来说,实现该要求很快就会变得过于复杂。

标签: odata sapui5 sap-fiori


【解决方案1】:

this answer所示,可以在XML中初步定义静态过滤器。

但是,如果需要动态确定过滤器值,则必须在 JS 中创建过滤器实例并将它们传递给树绑定。您可以将绑定定义保留在 XML 中,但聚合绑定应首先是 suspended: true(以避免不必要地发送多个请求)。

<Tree id="CatTree" items="{
  path: '/CategoriesSet',
  ...,
  suspended: true
}">
  <StandardTreeItem title="{CatName}" tooltip="{CatID}" />
</Tree>
// As soon as the Tree is accessible from JS:
const suspendedTreeBinding = myTree.getBinding("items");
suspendedTreeBinding.filter(aFilters, "Application");
suspendedTreeBinding.resume(); // starts sending a single data request but with the filter

无需事先致电oModel.read()


题外话,但尽量避免使用旧的工厂函数sap.ui.xmlfragment,因为它自 UI5 v1.58 以来已被弃用!请改用sap/ui/core/Fragment.load。例如。 like this.

【讨论】:

  • 哇! OData V2 绑定也可以使用挂起/恢复方法吗?
  • @Cmdd 是的。 suspend() / resume() 都是来自 sap/ui/model/Binding 的公共方法(因此适用于所有类型的绑定,甚至是 OData V2 绑定)。绑定定义(例如在 XML 中)中的属性 suspended: true 可用于所有 ManagedObjects / Controls。比如ODataListBinding,只有在调用.resume()之后才发送GET请求
  • @Cmdd 也适用于 OData V4:openui5.hana.ondemand.com/topic/…
  • 我认为我误解了文档,并且从未给他们适当的尝试。我认为它仅适用于 OData V4 :-)
  • @BoghyonHoffmann:感谢您的回复和题外话。我很感激,只是调整了片段。现在我正在尝试使用 suspend: true 属性。但不幸的是,它还没有工作。首次加载片段后立即调用后端。在我的 oDataService 或我的默认 oDataModel 中还有什么需要调整的吗?
【解决方案2】:

如果您想在开始时执行读取,可以将成功回调的结果存储在 JSONModel 中,然后将此模型绑定到 Fragment。

或者,您可以跳过第一个调用并仔细配置 Fragment 中的调用以满足您的需求。

实际上这正是 odata 模型的工作原理。

就我个人而言,我更喜欢第一个选项,因为在 javascript 中过滤比在声明式方法中更容易。

【讨论】:

  • 感谢您的回复。我想我不能使用 JSONModel,因为数据在 sap.m.tree 控件中使用,并且为了获得合适的树,使用 oDataModel 似乎更容易。如果我想为树使用 JSON 模型,那么它必须是嵌套的 JSON,但似乎很难将成功回调的结果转换为它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-02
相关资源
最近更新 更多