v2.ODataModel:哪个API更受欢迎? "bindElement" 还是 "read"?
v2.ODataModel: which API is more preferred? "bindElement" or "read"?
我设置 view.setModel(model)
,获取视图的模型,并请求 model.read("/entitySet('10000')")
。
然后用 /entitySet('10000')/properties
.
填充模型
但是很难将它们分配给视图字段,因为现在在视图中,<Text text="{property}">
不起作用。必须是 <Text text="{/entitySet('10000')/property}">
.
另一方面,如果我将视图的上下文绑定设置为 "/entitySet('10000')"
,那么 <Text text="{property}">
将开始工作。
首选哪种方法?什么时候使用 .read
?
如果我想直接在绑定上下文中使用 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)
}
});
对于table,它略有不同,因为它取决于您希望绑定的聚合,例如
oTable.bindRows({
path: "properties"
});
与以下相同:
<Table rows="{properties}" />
我几乎同意 Jorg 的观点,但不完全同意:
这实际上取决于您要实现的目标。如果希望从后端显示数据,那么最简单的方法是使用 this.getView().bindElement()
但是如果您需要在显示之前操作数据(例如格式化文本、显示来自 base64 字符串的图像等)或者如果您想使用一些现有数据创建新实体,或者更新现有数据 - this.getModel(sName).read()
是要走的路 - 因为您可以在 successCallback 中将读取实体及其所有深层实体设置为 JSONModel 并从 localModel 对其进行操作。
如果使用 localModel,则 dataBinding 在视图中几乎相同 - 除了您必须另外提供模型名称以从中获取数据。因此,例如,如果在 Model.read() 的 successCallback 中将数据设置为名为 "localModel" 的模型:
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);
}
})
然后在 XML 视图中你会指出
<Text text="{localModel>/mainPropertyName}"/>
// for displaying deep entities as List items or in Table
<List items="{localModel>/deepEntityName}">
<StandardListItem title="{localModel>propertyNamefromDeepEntity}" />
</List>
根据我使用更复杂的应用程序的经验,Read-Only - 我总是使用 Model.read()。
更具表现力总是很重要的。使用专为执行该任务而设计的 API。
比较两个变体:
myModel.read(<em>sPath</em>)
与 text="{/path/property}"
myControl.bindElement(<em>sPath</em>)
与 text="{property}"
我会对第一次调用感到困惑,而在第二次调用中,我会确切地知道你想要实现什么(你想要绑定元素。或者,bindObject
也可以用)。
框架也是如此。由于您准确地说明了您想要实现的目标,因此该框架可以根据您的意图改进其行为。 例如: 在 (route)PatternMatched
处理程序中,当用户导航到同一页面时,具有相同路径的 .bindElement
不会触发另一个请求,因为模型已经存储了实体从以前的电话。它可以立即显示结果。
然而,使用 .read
,框架不知道你想要实现什么,所以它会立即发送请求,而不管应用程序状态如何。
此外,第一个变体不是 future-proof。它依赖于缓存的结果。它几乎是一个 side-effect 它的工作原理。问题是不能保证这种行为在以后的版本中会继续有效。另外 V4 ODataModel 中不会有 read
方法。
TL;DR
v2.ODataModel#read
- 不会从响应创建
context
。重复 .read("<same path>")
总是发送一个新的请求。
- 表达能力差。鼓励应用开发者使用 client-side 模型(例如 JSONModel)。
- 应用程序失去上下文感知,增加 TCO,减少 future-proof。
bindElement or bindObject
- 根据响应创建
context
并将其存储在内部,以便同一请求可以立即 return 数据。
- 明确表达意图;应用程序和框架可以使用现有的 APIs.
- 更多future-proof:
<strong>v4.</strong>ODataModel
不支持手动读取.想象一下,您已经使用 v2ODataModel.read
-jsonModel.setData
方法构建了您的应用程序,并且您需要迁移到 v4
。玩得开心。 :)
老实说,我认为 v2.ODataModel#read
永远不应该成为 public 方法。我不鼓励任何人在手动读取 $count
值时使用 .read
except of。
如果实体值需要格式化,有开箱即用的格式化程序和绑定类型,也很容易扩展。
如果应用程序需要重构响应主体,通常是数据模型设计不当或服务不符合 OData 规范的标志。
我设置 view.setModel(model)
,获取视图的模型,并请求 model.read("/entitySet('10000')")
。
然后用 /entitySet('10000')/properties
.
但是很难将它们分配给视图字段,因为现在在视图中,<Text text="{property}">
不起作用。必须是 <Text text="{/entitySet('10000')/property}">
.
另一方面,如果我将视图的上下文绑定设置为 "/entitySet('10000')"
,那么 <Text text="{property}">
将开始工作。
首选哪种方法?什么时候使用 .read
?
如果我想直接在绑定上下文中使用 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)
}
});
对于table,它略有不同,因为它取决于您希望绑定的聚合,例如
oTable.bindRows({
path: "properties"
});
与以下相同:
<Table rows="{properties}" />
我几乎同意 Jorg 的观点,但不完全同意:
这实际上取决于您要实现的目标。如果希望从后端显示数据,那么最简单的方法是使用 this.getView().bindElement()
但是如果您需要在显示之前操作数据(例如格式化文本、显示来自 base64 字符串的图像等)或者如果您想使用一些现有数据创建新实体,或者更新现有数据 - this.getModel(sName).read()
是要走的路 - 因为您可以在 successCallback 中将读取实体及其所有深层实体设置为 JSONModel 并从 localModel 对其进行操作。
如果使用 localModel,则 dataBinding 在视图中几乎相同 - 除了您必须另外提供模型名称以从中获取数据。因此,例如,如果在 Model.read() 的 successCallback 中将数据设置为名为 "localModel" 的模型:
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);
}
})
然后在 XML 视图中你会指出
<Text text="{localModel>/mainPropertyName}"/>
// for displaying deep entities as List items or in Table
<List items="{localModel>/deepEntityName}">
<StandardListItem title="{localModel>propertyNamefromDeepEntity}" />
</List>
根据我使用更复杂的应用程序的经验,Read-Only - 我总是使用 Model.read()。
更具表现力总是很重要的。使用专为执行该任务而设计的 API。
比较两个变体:
myModel.read(<em>sPath</em>)
与text="{/path/property}"
myControl.bindElement(<em>sPath</em>)
与text="{property}"
我会对第一次调用感到困惑,而在第二次调用中,我会确切地知道你想要实现什么(你想要绑定元素。或者,bindObject
也可以用)。
框架也是如此。由于您准确地说明了您想要实现的目标,因此该框架可以根据您的意图改进其行为。 例如: 在 (route)PatternMatched
处理程序中,当用户导航到同一页面时,具有相同路径的 .bindElement
不会触发另一个请求,因为模型已经存储了实体从以前的电话。它可以立即显示结果。
然而,使用 .read
,框架不知道你想要实现什么,所以它会立即发送请求,而不管应用程序状态如何。
此外,第一个变体不是 future-proof。它依赖于缓存的结果。它几乎是一个 side-effect 它的工作原理。问题是不能保证这种行为在以后的版本中会继续有效。另外 V4 ODataModel 中不会有 read
方法。
TL;DR
v2.ODataModel#read
v2.ODataModel#read
- 不会从响应创建
context
。重复.read("<same path>")
总是发送一个新的请求。 - 表达能力差。鼓励应用开发者使用 client-side 模型(例如 JSONModel)。
- 应用程序失去上下文感知,增加 TCO,减少 future-proof。
bindElement or bindObject
bindElement or bindObject
- 根据响应创建
context
并将其存储在内部,以便同一请求可以立即 return 数据。 - 明确表达意图;应用程序和框架可以使用现有的 APIs.
- 更多future-proof:
<strong>v4.</strong>ODataModel
不支持手动读取.想象一下,您已经使用v2ODataModel.read
-jsonModel.setData
方法构建了您的应用程序,并且您需要迁移到v4
。玩得开心。 :)
老实说,我认为 v2.ODataModel#read
永远不应该成为 public 方法。我不鼓励任何人在手动读取 $count
值时使用 .read
except of。
如果实体值需要格式化,有开箱即用的格式化程序和绑定类型,也很容易扩展。
如果应用程序需要重构响应主体,通常是数据模型设计不当或服务不符合 OData 规范的标志。