v2.ODataModel:哪个API更受欢迎? “ bindElement”还是“ read”?

时间:2019-06-30 01:32:36

标签: sapui5

我设置了view.setModel(model),获取了视图的模型,并请求了model.read("/entitySet('10000')")。 然后,该模型将填充/entitySet('10000')/properties

但是很难将它们分配给视图字段,因为现在在视图中,<Text text="{property}">不起作用。它必须是<Text text="{/entitySet('10000')/property}">

另一方面,如果我将视图的上下文绑定设置为"/entitySet('10000')",那么<Text text="{property}">将开始工作。

哪个是首选方法?何时使用.read

3 个答案:

答案 0 :(得分:2)

如果我想直接在绑定上下文中使用OData调用的结果,我几乎从不使用.read。我唯一使用.read的情况是,我想在对结果进行任何操作之前先对其进行操作。

从sdk中查看此示例,例如:https://ui5.sap.com/#/entity/sap.ui.table.Table/sample/sap.ui.table.sample.OData

这种绑定的语法与read相似,但是事件有一些区别,根据要绑定的内容有几种不同类型的方法。例如,使用bindElement绑定到视图:

 this.getView().bindElement("/entitySet('1000')");

此后,可以使用<Text text="{property}" />来访问该特定实体 上的字段。

这是我当前应用中的一个带有事件和其他一些调用参数的示例:

this.getView().bindElement({
  path: `/Orders('${currentOrderNumber}')`,
  parameters: {
    expand: 'Texts'
  },
  events: {
    dataRequested: _ => this.getView().setBusy(true),
    dataReceived: data => {
      if (!this.getView().getBindingContext()) {
        // navigate to `Not Found` view
      }
    },
    change: _ => this.getView().setBusy(false)
  }
});

对于表,它稍有不同,因为它取决于您要绑定的聚合,例如

oTable.bindRows({
  path: "properties"
});

与以下相同:

<Table rows="{properties}" />

答案 1 :(得分:2)

表现力始终很重要。使用专门设计用于完成一项任务的API。

比较两个变体:

  1. myModel.read(sPath)text="{/path/property}"
  2. myModel.bindElement(sPath)text="{property}"

我对第一个电话感到困惑,而在第二个电话中,我确切地知道您想要实现什么(您想bind element)。

框架也是如此。由于您在说出要实现的目标,因此该框架可以根据您的意图改善其行为。 例如:(route)PatternMatched处理程序中,当用户导航到同一页面时,具有相同路径的.bindElement不会触发另一个请求,因为该模型已经存储了上一个实体呼叫。它可以立即显示结果。
但是,对于.read,框架不知道您要实现什么目标,因此无论应用程序状态如何,它都会立即发送请求。

此外,第一种变体没有耐久性。它依赖于缓存的结果。它几乎完全可以起到副作用。问题是不能保证此行为在更高版本中将继续起作用。


TL; DR

ODataModel#read

  • 从响应中创建context。重复.read("<same path>")总是发送一个新请求。
  • 缺乏表现力。鼓励应用程序开发人员使用客户端模型(例如JSONModel)。
  • 应用程序失去了上下文意识,提高了总体拥有成本,降低了对未来的要求。


ODataModel#bindElement

  • 从响应中创建context并将其存储在内部,以便同一请求可以立即返回数据。
  • 明确表达意图;应用程序以及框架都可以使用现有的API。
  • 更具前瞻性:v4.ODataModel 不支持手动阅读。想象一下,您已经使用v2.ODataModel#read + JSONModel构建了应用程序,并且需要迁移到v4。玩得开心:)



P.S。:老实说,ODataModel#read不应该成为一种公开方法(?为时已晚)。我绝不鼓励任何人在手动读取.read值时使用$count 外。

如果需要对实体值进行格式化,则相应地有格式化程序和绑定类型。

如果应用程序需要重组响应主体,通常表明数据模型设计不良或服务不符合OData规范。

答案 2 :(得分:-2)

我几乎同意Jorg,但并不完全同意:

这实际上取决于您要实现的目标。如果希望从后端显示数据,那么最简单的方法是使用this.getView().bindElement()

,但是如果您需要在显示之前处理数据(例如设置文本格式,显示base64字符串中的图像等),或者如果您想使用某些现有数据来创建新实体,或者更新现有数据-{ {1}}是一种解决方法-您可以在successCallback中将read实体及其所有深层实体设置为JSONModel,然后从localModel中对其进行操作。

如果使用localModel,则dataBinding在视图中几乎相同-除非必须另外提供模型名称以从中获取数据。因此,例如,如果在Model.read()的successCallback中,将数据设置为名为“ localModel”的模型:

this.getModel(sName).read()

然后在XML视图中指出

this.getModel().read(sObjectPath, {
            urlParameters: {
                $expand: ""
            },
            success: function (oData) {
              // "localModel" is name you gave in onInit function to your new JSONMOdel, when setting it to View e.g. this.getView().setModel(oJSONMOdel, "localModel")
               this.getModel("localModel").setData(oData);
            } 
          })

根据我在处理更复杂的只读应用程序方面的经验,我始终使用Model.read()。