@openui5/sap.ui.core 1.96.2 → 1.97.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/.eslintrc.json +2 -2
  2. package/.reuse/dep5 +1 -1
  3. package/THIRDPARTY.txt +2 -1
  4. package/package.json +1 -1
  5. package/src/jquery.sap.global.js +1 -1
  6. package/src/jquery.sap.properties.js +1 -1
  7. package/src/jquery.sap.resources.js +2 -2
  8. package/src/jquery.sap.script.js +1 -1
  9. package/src/jquery.sap.storage.js +3 -3
  10. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  11. package/src/sap/base/util/restricted/_castArray.js +1 -1
  12. package/src/sap/base/util/restricted/_compact.js +1 -1
  13. package/src/sap/base/util/restricted/_curry.js +1 -1
  14. package/src/sap/base/util/restricted/_debounce.js +1 -1
  15. package/src/sap/base/util/restricted/_difference.js +1 -1
  16. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  17. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  18. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  19. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  20. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  21. package/src/sap/base/util/restricted/_flatten.js +1 -1
  22. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  23. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  24. package/src/sap/base/util/restricted/_intersection.js +1 -1
  25. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  26. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  27. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  28. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  29. package/src/sap/base/util/restricted/_isNil.js +1 -1
  30. package/src/sap/base/util/restricted/_max.js +1 -1
  31. package/src/sap/base/util/restricted/_merge.js +1 -1
  32. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  33. package/src/sap/base/util/restricted/_min.js +1 -1
  34. package/src/sap/base/util/restricted/_omit.js +1 -1
  35. package/src/sap/base/util/restricted/_pick.js +1 -1
  36. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  37. package/src/sap/base/util/restricted/_throttle.js +1 -1
  38. package/src/sap/base/util/restricted/_toArray.js +1 -1
  39. package/src/sap/base/util/restricted/_union.js +1 -1
  40. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  41. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  42. package/src/sap/base/util/restricted/_uniq.js +1 -1
  43. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  44. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  45. package/src/sap/base/util/restricted/_without.js +1 -1
  46. package/src/sap/base/util/restricted/_xor.js +1 -1
  47. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  48. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  49. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  50. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  51. package/src/sap/ui/Device.js +4 -4
  52. package/src/sap/ui/Global.js +11 -16
  53. package/src/sap/ui/base/Event.js +1 -1
  54. package/src/sap/ui/base/EventProvider.js +1 -1
  55. package/src/sap/ui/base/Interface.js +1 -1
  56. package/src/sap/ui/base/ManagedObject.js +3 -3
  57. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  58. package/src/sap/ui/base/Metadata.js +1 -3
  59. package/src/sap/ui/base/Object.js +1 -1
  60. package/src/sap/ui/base/ObjectPool.js +1 -1
  61. package/src/sap/ui/core/.library +1 -27
  62. package/src/sap/ui/core/AppCacheBuster.js +4 -4
  63. package/src/sap/ui/core/BusyIndicator.js +1 -1
  64. package/src/sap/ui/core/Component.js +31 -9
  65. package/src/sap/ui/core/ComponentContainer.js +1 -1
  66. package/src/sap/ui/core/ComponentMetadata.js +1 -1
  67. package/src/sap/ui/core/ComponentSupport.js +1 -1
  68. package/src/sap/ui/core/Control.js +2 -2
  69. package/src/sap/ui/core/Core.js +2 -2
  70. package/src/sap/ui/core/CustomData.js +1 -1
  71. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  72. package/src/sap/ui/core/Element.js +2 -6
  73. package/src/sap/ui/core/ElementMetadata.js +1 -1
  74. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  75. package/src/sap/ui/core/EventBus.js +1 -1
  76. package/src/sap/ui/core/Fragment.js +1 -1
  77. package/src/sap/ui/core/HTML.js +3 -3
  78. package/src/sap/ui/core/History.js +1 -1
  79. package/src/sap/ui/core/Icon.js +1 -1
  80. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  81. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  82. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  83. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  84. package/src/sap/ui/core/InvisibleText.js +1 -1
  85. package/src/sap/ui/core/Item.js +1 -1
  86. package/src/sap/ui/core/LabelEnablement.js +1 -1
  87. package/src/sap/ui/core/LayoutData.js +1 -1
  88. package/src/sap/ui/core/ListItem.js +1 -1
  89. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  90. package/src/sap/ui/core/Locale.js +1 -1
  91. package/src/sap/ui/core/LocaleData.js +3 -3
  92. package/src/sap/ui/core/Manifest.js +1 -1
  93. package/src/sap/ui/core/Message.js +1 -1
  94. package/src/sap/ui/core/RenderManager.js +3 -3
  95. package/src/sap/ui/core/Renderer.js +1 -1
  96. package/src/sap/ui/core/ResizeHandler.js +1 -1
  97. package/src/sap/ui/core/ScrollBar.js +4 -3
  98. package/src/sap/ui/core/SeparatorItem.js +1 -1
  99. package/src/sap/ui/core/ThemeCheck.js +2 -2
  100. package/src/sap/ui/core/Title.js +1 -1
  101. package/src/sap/ui/core/TooltipBase.js +1 -1
  102. package/src/sap/ui/core/UIArea.js +3 -3
  103. package/src/sap/ui/core/UIComponent.js +1 -1
  104. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  105. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  106. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  107. package/src/sap/ui/core/XMLComposite.js +1 -1
  108. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  109. package/src/sap/ui/core/XMLTemplateProcessor.js +19 -5
  110. package/src/sap/ui/core/cache/LRUPersistentCache.js +4 -2
  111. package/src/sap/ui/core/date/UniversalDateUtils.js +33 -0
  112. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  113. package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
  114. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  115. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  116. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  117. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  118. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  119. package/src/sap/ui/core/library.js +5 -5
  120. package/src/sap/ui/core/message/ControlMessageProcessor.js +5 -5
  121. package/src/sap/ui/core/message/Message.js +1 -1
  122. package/src/sap/ui/core/message/MessageManager.js +1 -1
  123. package/src/sap/ui/core/message/MessageParser.js +1 -1
  124. package/src/sap/ui/core/message/MessageProcessor.js +22 -12
  125. package/src/sap/ui/core/messagebundle_fr.properties +7 -7
  126. package/src/sap/ui/core/messagebundle_ru.properties +21 -21
  127. package/src/sap/ui/core/mvc/Controller.js +4 -4
  128. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  129. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  130. package/src/sap/ui/core/mvc/JSView.js +1 -1
  131. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  132. package/src/sap/ui/core/mvc/View.js +1 -1
  133. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  134. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  135. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  136. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  137. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  138. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  139. package/src/sap/ui/core/rules/Misc.support.js +51 -1
  140. package/src/sap/ui/core/rules/Rendering.support.js +1 -4
  141. package/src/sap/ui/core/rules/View.support.js +14 -46
  142. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  143. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  144. package/src/sap/ui/core/service/Service.js +1 -1
  145. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  146. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  147. package/src/sap/ui/core/support/Plugin.js +2 -2
  148. package/src/sap/ui/core/support/RuleEngineOpaExtension.js +0 -1
  149. package/src/sap/ui/core/support/Support.js +1 -1
  150. package/src/sap/ui/core/support/controls/TreeViewer.js +1 -1
  151. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  152. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  153. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  154. package/src/sap/ui/core/support/plugins/Performance.js +1 -2
  155. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  156. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  157. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  158. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  159. package/src/sap/ui/core/support/techinfo/TechnicalInfo.js +1 -1
  160. package/src/sap/ui/core/support/trace/E2eTraceLib.js +3 -3
  161. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  162. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  163. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  164. package/src/sap/ui/core/tmpl/Template.js +1 -1
  165. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  166. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  167. package/src/sap/ui/core/util/Export.js +1 -1
  168. package/src/sap/ui/core/util/ExportCell.js +1 -1
  169. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  170. package/src/sap/ui/core/util/ExportRow.js +1 -1
  171. package/src/sap/ui/core/util/ExportType.js +1 -1
  172. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  173. package/src/sap/ui/core/util/File.js +1 -1
  174. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  175. package/src/sap/ui/core/util/MockServer.js +2 -2
  176. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  177. package/src/sap/ui/core/util/reflection/JsControlTreeModifier.js +4 -4
  178. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  179. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  180. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  181. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  182. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  183. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  184. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  185. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  186. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  187. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  188. package/src/sap/ui/debug/ControlTree.js +1 -1
  189. package/src/sap/ui/debug/DebugEnv.js +1 -1
  190. package/src/sap/ui/debug/PropertyList.js +1 -1
  191. package/src/sap/ui/model/ChangeReason.js +1 -1
  192. package/src/sap/ui/model/ClientListBinding.js +7 -0
  193. package/src/sap/ui/model/ClientModel.js +6 -5
  194. package/src/sap/ui/model/ClientTreeBindingAdapter.js +1 -1
  195. package/src/sap/ui/model/CompositeDataState.js +1 -1
  196. package/src/sap/ui/model/CompositeType.js +1 -1
  197. package/src/sap/ui/model/DataState.js +1 -1
  198. package/src/sap/ui/model/ListBinding.js +24 -5
  199. package/src/sap/ui/model/MetaModel.js +1 -1
  200. package/src/sap/ui/model/Model.js +5 -10
  201. package/src/sap/ui/model/SelectionModel.js +1 -1
  202. package/src/sap/ui/model/SimpleType.js +1 -1
  203. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  204. package/src/sap/ui/model/TreeBindingAdapter.js +0 -2
  205. package/src/sap/ui/model/TreeBindingUtils.js +2 -0
  206. package/src/sap/ui/model/Type.js +1 -1
  207. package/src/sap/ui/model/analytics/AnalyticalBinding.js +12 -6
  208. package/src/sap/ui/model/analytics/AnalyticalTreeBindingAdapter.js +16 -18
  209. package/src/sap/ui/model/json/JSONModel.js +7 -7
  210. package/src/sap/ui/model/json/JSONPropertyBinding.js +1 -1
  211. package/src/sap/ui/model/message/MessageModel.js +3 -3
  212. package/src/sap/ui/model/message/MessagePropertyBinding.js +1 -1
  213. package/src/sap/ui/model/odata/AnnotationHelper.js +2 -2
  214. package/src/sap/ui/model/odata/AnnotationParser.js +4 -2
  215. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  216. package/src/sap/ui/model/odata/ODataListBinding.js +61 -38
  217. package/src/sap/ui/model/odata/ODataMessageParser.js +2 -2
  218. package/src/sap/ui/model/odata/ODataMetaModel.js +3 -3
  219. package/src/sap/ui/model/odata/ODataMetadata.js +136 -85
  220. package/src/sap/ui/model/odata/ODataModel.js +442 -215
  221. package/src/sap/ui/model/odata/ODataPropertyBinding.js +7 -5
  222. package/src/sap/ui/model/odata/ODataTreeBindingAdapter.js +27 -17
  223. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +440 -260
  224. package/src/sap/ui/model/odata/ODataUtils.js +24 -9
  225. package/src/sap/ui/model/odata/_AnnotationHelperBasics.js +2 -1
  226. package/src/sap/ui/model/odata/_AnnotationHelperExpression.js +10 -8
  227. package/src/sap/ui/model/odata/_ODataMetaModelUtils.js +6 -4
  228. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  229. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  230. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  231. package/src/sap/ui/model/odata/type/Date.js +1 -1
  232. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  233. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  234. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  235. package/src/sap/ui/model/odata/type/Decimal.js +5 -1
  236. package/src/sap/ui/model/odata/type/Double.js +1 -1
  237. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  238. package/src/sap/ui/model/odata/type/Int.js +1 -1
  239. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  240. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  241. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  242. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  243. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  244. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  245. package/src/sap/ui/model/odata/type/Single.js +1 -1
  246. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  247. package/src/sap/ui/model/odata/type/String.js +1 -1
  248. package/src/sap/ui/model/odata/type/Time.js +1 -1
  249. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  250. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  251. package/src/sap/ui/model/odata/type/UnitMixin.js +0 -1
  252. package/src/sap/ui/model/odata/v2/Context.js +42 -11
  253. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  254. package/src/sap/ui/model/odata/v2/ODataListBinding.js +205 -88
  255. package/src/sap/ui/model/odata/v2/ODataModel.js +154 -89
  256. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +162 -89
  257. package/src/sap/ui/model/odata/v2/_CreatedContextsCache.js +52 -2
  258. package/src/sap/ui/model/odata/v4/Context.js +48 -7
  259. package/src/sap/ui/model/odata/v4/ODataBinding.js +55 -24
  260. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +67 -19
  261. package/src/sap/ui/model/odata/v4/ODataListBinding.js +211 -78
  262. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +1 -1
  263. package/src/sap/ui/model/odata/v4/ODataModel.js +2 -1
  264. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +36 -23
  265. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +3 -3
  266. package/src/sap/ui/model/odata/v4/lib/_Cache.js +106 -11
  267. package/src/sap/ui/model/odata/v4/lib/_Helper.js +33 -3
  268. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +11 -2
  269. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  270. package/src/sap/ui/model/type/Boolean.js +1 -1
  271. package/src/sap/ui/model/type/Currency.js +1 -1
  272. package/src/sap/ui/model/type/Date.js +1 -1
  273. package/src/sap/ui/model/type/DateInterval.js +1 -1
  274. package/src/sap/ui/model/type/DateTime.js +1 -1
  275. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  276. package/src/sap/ui/model/type/FileSize.js +1 -1
  277. package/src/sap/ui/model/type/Float.js +1 -1
  278. package/src/sap/ui/model/type/Integer.js +1 -1
  279. package/src/sap/ui/model/type/String.js +1 -1
  280. package/src/sap/ui/model/type/Time.js +1 -1
  281. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  282. package/src/sap/ui/model/type/Unit.js +1 -1
  283. package/src/sap/ui/model/xml/XMLModel.js +5 -5
  284. package/src/sap/ui/model/xml/XMLPropertyBinding.js +1 -1
  285. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  286. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  287. package/src/sap/ui/test/actions/Action.js +9 -2
  288. package/src/sap/ui/test/actions/Press.js +28 -1
  289. package/src/sap/ui/test/generic/_EnforceSemanticRendering.js +111 -0
  290. package/src/sap/ui/util/Mobile.js +28 -39
  291. package/src/sap/ui/util/Storage.js +1 -1
  292. package/src/ui5loader.js +6 -6
  293. package/ui5.yaml +244 -1
  294. package/src/sap/ui/core/CustomizingConfiguration.js +0 -47
  295. package/src/sap/ui/thirdparty/baseuri.js +0 -1
  296. package/src/sap/ui/thirdparty/es6-object-assign.js +0 -1
  297. package/src/sap/ui/thirdparty/es6-promise.js +0 -1
  298. package/src/sap/ui/thirdparty/es6-shim-nopromise.js +0 -1
  299. package/src/sap/ui/thirdparty/es6-string-methods.js +0 -1
  300. package/src/sap/ui/thirdparty/flexie.js +0 -1
  301. package/src/sap/ui/thirdparty/unorm.js +0 -1
  302. package/src/sap/ui/thirdparty/unormdata.js +0 -1
@@ -76,7 +76,7 @@ sap.ui.define([
76
76
  * @mixes sap.ui.model.odata.v4.ODataParentBinding
77
77
  * @public
78
78
  * @since 1.37.0
79
- * @version 1.96.2
79
+ * @version 1.97.0
80
80
  * @borrows sap.ui.model.odata.v4.ODataBinding#getGroupId as #getGroupId
81
81
  * @borrows sap.ui.model.odata.v4.ODataBinding#getRootBinding as #getRootBinding
82
82
  * @borrows sap.ui.model.odata.v4.ODataBinding#getUpdateGroupId as #getUpdateGroupId
@@ -122,6 +122,14 @@ sap.ui.define([
122
122
  ? null
123
123
  : Context.createNewContext(oModel, this, sPath);
124
124
  this.sOperationMode = mParameters.$$operationMode || oModel.sOperationMode;
125
+ // map<string,sap.ui.model.odata.v4.Context>
126
+ // Maps a string path to a v4.Context with that path. A context may either be
127
+ // - an element of this.aContexts (then it knows its index) or
128
+ // - a value of this.mPreviousContextsByPath.
129
+ // Contexts which have previously been part of this.aContexts are parked here for
130
+ // reuse (and thus still remember their index) and get destroyed by
131
+ // #destroyPreviousContexts after the next call to #createContexts.
132
+ // A kept-alive context may be parked here for a longer time, with undefined index.
125
133
  this.mPreviousContextsByPath = {};
126
134
  this.aPreviousData = [];
127
135
  this.bSharedRequest = mParameters.$$sharedRequest || oModel.bSharedRequests;
@@ -215,13 +223,18 @@ sap.ui.define([
215
223
  * An entity with the ETag of the binding for which the deletion was requested. This is
216
224
  * provided if the deletion is delegated from a context binding with empty path to a list
217
225
  * binding.
226
+ * @param {boolean} [bDoNotRequestCount]
227
+ * Whether not to request the new count from the server; useful in case of
228
+ * {@link sap.ui.model.odata.v4.Context#replaceWith} where it is known that the count remains
229
+ * unchanged
218
230
  * @returns {Promise}
219
231
  * A promise which is resolved without a result in case of success, or rejected with an
220
232
  * instance of <code>Error</code> in case of failure.
221
233
  *
222
234
  * @private
223
235
  */
224
- ODataListBinding.prototype._delete = function (oGroupLock, sEditUrl, oContext, oETagEntity) {
236
+ ODataListBinding.prototype._delete = function (oGroupLock, sEditUrl, oContext, oETagEntity,
237
+ bDoNotRequestCount) {
225
238
  var bDestroy,
226
239
  bFireChange = false,
227
240
  sPath = oContext.iIndex === undefined
@@ -231,7 +244,7 @@ sap.ui.define([
231
244
  bReadCount = false,
232
245
  that = this;
233
246
 
234
- return this.deleteFromCache(oGroupLock, sEditUrl, sPath, oETagEntity,
247
+ return this.deleteFromCache(oGroupLock, sEditUrl, sPath, oETagEntity, bDoNotRequestCount,
235
248
  function (iIndex, aEntities) {
236
249
  var sContextPath, sPredicate, sResolvedPath, i$skipIndex, i;
237
250
 
@@ -627,6 +640,9 @@ sap.ui.define([
627
640
  if (this.mParameters.$$aggregation) {
628
641
  throw new Error("Unsupported $$aggregation at " + this);
629
642
  }
643
+ if (this.bSharedRequest) {
644
+ throw new Error("Unsupported $$sharedRequest at " + this);
645
+ }
630
646
  };
631
647
 
632
648
  /**
@@ -719,22 +735,34 @@ sap.ui.define([
719
735
  * @param {boolean} [bAtEnd]
720
736
  * Whether the entity is inserted at the end of the list. When creating multiple entities,
721
737
  * this parameter must have the same value for each entity. Supported since 1.66.0
738
+ * @param {boolean} [bInactive]
739
+ * Create an inactive context. Such a context will only be sent to the server after the first
740
+ * property update. From then on it behaves like any other created context. This parameter is
741
+ * experimental and its implementation may still change. Do not use it in productive code yet.
742
+ * Supported since 1.97.0
722
743
  * @returns {sap.ui.model.odata.v4.Context}
723
744
  * The context object for the created entity; its method
724
745
  * {@link sap.ui.model.odata.v4.Context#created} returns a promise that is resolved when the
725
746
  * creation is finished
726
747
  * @throws {Error}
727
- * If the binding's root binding is suspended, if a relative binding is unresolved, if
728
- * entities are created both at the start and at the end, or if <code>bAtEnd</code> is
729
- * <code>true</code> and the binding does not know the final length.
730
- *
748
+ * If
749
+ * <ul>
750
+ * <li> the binding's root binding is suspended,
751
+ * <li> a relative binding is unresolved,
752
+ * <li> entities are created both at the start and at the end,
753
+ * <li> <code>bAtEnd</code> is <code>true</code> and the binding does not know the final
754
+ * length,
755
+ * <li> <code>bInactive</code> is <code>true</code> and the update group ID does not have
756
+ * {@link sap.ui.model.odata.v4.SubmitMode.Auto}.
757
+ * </ul>
731
758
  * @public
732
759
  * @since 1.43.0
733
760
  */
734
- ODataListBinding.prototype.create = function (oInitialData, bSkipRefresh, bAtEnd) {
761
+ ODataListBinding.prototype.create = function (oInitialData, bSkipRefresh, bAtEnd, bInactive) {
735
762
  var oContext,
736
763
  oCreatePathPromise = this.fetchResourcePath(),
737
764
  oCreatePromise,
765
+ sGroupId = this.getUpdateGroupId(),
738
766
  oGroupLock,
739
767
  sResolvedPath = this.getResolvedPath(),
740
768
  sTransientPredicate = "($uid=" + uid() + ")",
@@ -757,8 +785,16 @@ sap.ui.define([
757
785
  }
758
786
  this.bCreatedAtEnd = bAtEnd;
759
787
 
788
+ if (bInactive) {
789
+ if (!this.oModel.isAutoGroup(sGroupId)) {
790
+ throw new Error("bInactive only supported for update group with SubmitMode.Auto: "
791
+ + this);
792
+ }
793
+ sGroupId = "$inactive." + sGroupId;
794
+ }
795
+
760
796
  // only for createInCache
761
- oGroupLock = this.lockGroup(undefined, true, true, function () {
797
+ oGroupLock = this.lockGroup(sGroupId, true, true, function () {
762
798
  that.destroyCreated(oContext, true);
763
799
  return Promise.resolve().then(function () {
764
800
  // Fire the change asynchronously so that Cache#delete is finished and #getContexts
@@ -1022,10 +1058,45 @@ sap.ui.define([
1022
1058
  * @see sap.ui.model.odata.v4.ODataBinding#doCreateCache
1023
1059
  */
1024
1060
  ODataListBinding.prototype.doCreateCache = function (sResourcePath, mQueryOptions, oContext,
1025
- sDeepResourcePath) {
1026
- return _AggregationCache.create(this.oModel.oRequestor, sResourcePath, sDeepResourcePath,
1061
+ sDeepResourcePath, bOldCacheReadOnly, oOldCache) {
1062
+ var sBindingPath,
1063
+ aKeptElementPaths,
1064
+ oCache,
1065
+ that = this;
1066
+
1067
+ if (oOldCache && oOldCache.getResourcePath() === sResourcePath
1068
+ && oOldCache.$deepResourcePath === sDeepResourcePath) {
1069
+ sBindingPath = this.oHeaderContext.getPath();
1070
+ aKeptElementPaths = Object.keys(this.mPreviousContextsByPath).filter(function (sPath) {
1071
+ return that.mPreviousContextsByPath[sPath].isKeepAlive();
1072
+ });
1073
+
1074
+ if (aKeptElementPaths.length && !bOldCacheReadOnly) {
1075
+ oOldCache.reset(aKeptElementPaths.map(function (sPath) {
1076
+ return _Helper.getRelativePath(sPath, sBindingPath);
1077
+ }));
1078
+ // Note: #inheritQueryOptions as called below should not matter in case of own
1079
+ // requests, which are a precondition for kept-alive elements
1080
+ oOldCache.setQueryOptions(mQueryOptions, true);
1081
+
1082
+ return oOldCache;
1083
+ }
1084
+ }
1085
+
1086
+ oCache = _AggregationCache.create(this.oModel.oRequestor, sResourcePath, sDeepResourcePath,
1027
1087
  this.mParameters.$$aggregation, this.inheritQueryOptions(mQueryOptions, oContext),
1028
1088
  this.oModel.bAutoExpandSelect, this.bSharedRequest);
1089
+
1090
+ if (aKeptElementPaths && aKeptElementPaths.length) {
1091
+ oCache.setLateQueryOptions(oOldCache.getLateQueryOptions());
1092
+ aKeptElementPaths.forEach(function (sPath) {
1093
+ oCache.addKeptElement(
1094
+ oOldCache.getValue(_Helper.getRelativePath(sPath, sBindingPath)));
1095
+ that.mPreviousContextsByPath[sPath].checkUpdate(); // add change listeners
1096
+ });
1097
+ }
1098
+
1099
+ return oCache;
1029
1100
  };
1030
1101
 
1031
1102
  /**
@@ -1043,6 +1114,59 @@ sap.ui.define([
1043
1114
  });
1044
1115
  };
1045
1116
 
1117
+ /**
1118
+ * Replaces the given old context with a new one for the given element and key predicate,
1119
+ * placing the new one at the same index and returning it. If a context for the given key
1120
+ * predicate already exists, it is reused. A newly created context will be kept-alive if the old
1121
+ * context was, and then it will share the <code>fnOnBeforeDestroy</code> method - but it will
1122
+ * be called with the new context as first argument.
1123
+ *
1124
+ * @param {sap.ui.model.odata.v4.Context} oOldContext - The old context
1125
+ * @param {object} oElement - The element data
1126
+ * @param {string} sPredicate - The key predicate
1127
+ * @returns {sap.ui.model.odata.v4.Context} - The new context
1128
+ * @throws {Error} If a reused context is already part of the collection (has an index)
1129
+ *
1130
+ * @private
1131
+ */
1132
+ ODataListBinding.prototype.doReplaceWith = function (oOldContext, oElement, sPredicate) {
1133
+ var iIndex = oOldContext.iIndex,
1134
+ bKeepAlive = oOldContext.isKeepAlive(),
1135
+ bNew,
1136
+ fnOnBeforeDestroy = oOldContext.fnOnBeforeDestroy,
1137
+ fnOnBeforeDestroyClone,
1138
+ sPath = this.oHeaderContext.getPath() + sPredicate,
1139
+ oResult = this.mPreviousContextsByPath[sPath];
1140
+
1141
+ if (oResult) {
1142
+ if (oResult.iIndex !== undefined) {
1143
+ throw new Error("Unexpected index: " + oResult);
1144
+ }
1145
+ oResult.iIndex = iIndex;
1146
+ delete this.mPreviousContextsByPath[sPath];
1147
+ } else {
1148
+ oResult = Context.create(this.oModel, this, sPath, iIndex);
1149
+ bNew = true;
1150
+ }
1151
+ oOldContext.iIndex = undefined;
1152
+ this.aContexts[iIndex] = oResult;
1153
+ this.oCache.doReplaceWith(iIndex, oElement);
1154
+ if (bKeepAlive) {
1155
+ this.mPreviousContextsByPath[oOldContext.getPath()] = oOldContext;
1156
+ if (bNew) {
1157
+ if (fnOnBeforeDestroy) {
1158
+ fnOnBeforeDestroyClone
1159
+ = (fnOnBeforeDestroy.$original || fnOnBeforeDestroy).bind(null, oResult);
1160
+ fnOnBeforeDestroyClone.$original = fnOnBeforeDestroy;
1161
+ }
1162
+ oResult.setKeepAlive(true, fnOnBeforeDestroyClone);
1163
+ }
1164
+ }
1165
+ this._fireChange({reason : ChangeReason.Change});
1166
+
1167
+ return oResult;
1168
+ };
1169
+
1046
1170
  /**
1047
1171
  * @override
1048
1172
  * @see sap.ui.model.odata.v4.ODataParentBinding#doSetProperty
@@ -1107,43 +1231,6 @@ sap.ui.define([
1107
1231
  });
1108
1232
  };
1109
1233
 
1110
- /**
1111
- * Creates a cache for this binding if a cache is needed and updates <code>oCachePromise</code>.
1112
- * Copies the data for kept-alive contexts and the late query options from the old cache to the
1113
- * new one.
1114
- *
1115
- * @private
1116
- */
1117
- // @override sap.ui.model.odata.v4.ODataBinding#fetchCache
1118
- ODataListBinding.prototype.fetchCache = function () {
1119
- var oOldCache = this.oCache,
1120
- sBindingPath = this.getResolvedPath(),
1121
- bKeptDataAdded,
1122
- that = this;
1123
-
1124
- asODataParentBinding.prototype.fetchCache.apply(this, arguments);
1125
-
1126
- if (oOldCache) {
1127
- this.oCachePromise.then(function (oCache) {
1128
- Object.keys(that.mPreviousContextsByPath).forEach(function (sPath) {
1129
- var oContext = that.mPreviousContextsByPath[sPath];
1130
-
1131
- if (oContext.isKeepAlive()) {
1132
- // either absolute or $$ownRequest === true
1133
- // ->has own cache, see #checkKeepAlive
1134
- oCache.addKeptElement(
1135
- oOldCache.getValue(_Helper.getRelativePath(sPath, sBindingPath)));
1136
- oContext.checkUpdate(); // add change listeners
1137
- bKeptDataAdded = true;
1138
- }
1139
- });
1140
- if (bKeptDataAdded) {
1141
- oCache.setLateQueryOptions(oOldCache.getLateQueryOptions());
1142
- }
1143
- }); // no catch; if the new cache can't be created, data for kept-alive contexts is lost
1144
- }
1145
- };
1146
-
1147
1234
  /**
1148
1235
  * Fetches the data and creates contexts for the given range.
1149
1236
  *
@@ -1499,10 +1586,11 @@ sap.ui.define([
1499
1586
  };
1500
1587
 
1501
1588
  /**
1502
- * Filters the list with the given filters.
1589
+ * Filters the list with the given filters. Since 1.97.0, if filters are unchanged, no request
1590
+ * is sent, regardless of pending changes.
1503
1591
  *
1504
- * If there are pending changes an error is thrown. Use {@link #hasPendingChanges} to check if
1505
- * there are pending changes. If there are changes, call
1592
+ * If there are pending changes that cannot be ignored, an error is thrown. Use
1593
+ * {@link #hasPendingChanges} to check if there are such pending changes. If there are, call
1506
1594
  * {@link sap.ui.model.odata.v4.ODataModel#submitBatch} to submit the changes or
1507
1595
  * {@link sap.ui.model.odata.v4.ODataModel#resetChanges} to reset the changes before calling
1508
1596
  * {@link #filter}.
@@ -1543,8 +1631,10 @@ sap.ui.define([
1543
1631
  * @returns {this}
1544
1632
  * <code>this</code> to facilitate method chaining
1545
1633
  * @throws {Error}
1546
- * If there are pending changes or if an unsupported operation mode is used (see
1547
- * {@link sap.ui.model.odata.v4.ODataModel#bindList})
1634
+ * If there are pending changes that cannot be ignored or if an unsupported operation mode is
1635
+ * used (see {@link sap.ui.model.odata.v4.ODataModel#bindList}). Since 1.97.0, pending changes
1636
+ * are ignored if they relate to a
1637
+ * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding.
1548
1638
  *
1549
1639
  * @public
1550
1640
  * @see sap.ui.model.ListBinding#filter
@@ -1553,17 +1643,25 @@ sap.ui.define([
1553
1643
  */
1554
1644
  // @override sap.ui.model.ListBinding#filter
1555
1645
  ODataListBinding.prototype.filter = function (vFilters, sFilterType) {
1646
+ var aFilters = _Helper.toArray(vFilters);
1647
+
1556
1648
  if (this.sOperationMode !== OperationMode.Server) {
1557
1649
  throw new Error("Operation mode has to be sap.ui.model.odata.OperationMode.Server");
1558
1650
  }
1559
- if (this.hasPendingChanges()) {
1651
+
1652
+ if (sFilterType === FilterType.Control && _Helper.deepEqual(aFilters, this.aFilters)
1653
+ || _Helper.deepEqual(aFilters, this.aApplicationFilters)) {
1654
+ return this;
1655
+ }
1656
+
1657
+ if (this.hasPendingChanges(true)) {
1560
1658
  throw new Error("Cannot filter due to pending changes");
1561
1659
  }
1562
1660
 
1563
1661
  if (sFilterType === FilterType.Control) {
1564
- this.aFilters = _Helper.toArray(vFilters);
1662
+ this.aFilters = aFilters;
1565
1663
  } else {
1566
- this.aApplicationFilters = _Helper.toArray(vFilters);
1664
+ this.aApplicationFilters = aFilters;
1567
1665
  }
1568
1666
 
1569
1667
  if (this.isRootBindingSuspended()) {
@@ -1690,7 +1788,7 @@ sap.ui.define([
1690
1788
  detailedReason : "RemoveVirtualContext",
1691
1789
  reason : ChangeReason.Change
1692
1790
  });
1693
- that.reset(ChangeReason.Refresh);
1791
+ that.reset(ChangeReason.Refresh, true);
1694
1792
  }
1695
1793
  oVirtualContext.destroy();
1696
1794
  });
@@ -2298,7 +2396,8 @@ sap.ui.define([
2298
2396
  }
2299
2397
 
2300
2398
  // add the context binding's query options as late query options
2301
- if (!this.aggregateQueryOptions(mEntityQueryOptions, "", /*bImmutable*/true)) {
2399
+ if (!this.aggregateQueryOptions(mEntityQueryOptions, _Helper.getMetaPath(sEntityPath),
2400
+ /*bImmutable*/true)) {
2302
2401
  throw new Error(oEntityContext + ": could not move the entity. Probably a list binding"
2303
2402
  + " w/o $$ownRequest depends on it");
2304
2403
  }
@@ -2357,9 +2456,13 @@ sap.ui.define([
2357
2456
 
2358
2457
  if (oCache && !oPromise) { // do not refresh twice
2359
2458
  that.removeCachesAndMessages(sResourcePathPrefix);
2360
- that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/true);
2459
+ that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/true, bKeepCacheOnError);
2361
2460
  oKeptElementsPromise = that.oCachePromise.then(function (oNewCache) {
2362
2461
  return oNewCache.refreshKeptElements(that.lockGroup(sGroupId), onRemove);
2462
+ }).catch(function (oError) {
2463
+ that.oModel.reportError("Failed to refresh kept-alive elements", sClassName,
2464
+ oError);
2465
+ throw oError;
2363
2466
  });
2364
2467
  if (that.iCurrentEnd > 0) {
2365
2468
  oPromise = that.createRefreshPromise().catch(function (oError) {
@@ -2772,23 +2875,29 @@ sap.ui.define([
2772
2875
  * A change reason; if given, a refresh event with this reason is fired and the next
2773
2876
  * getContexts() fires a change event with this reason. Change reason "change" is ignored
2774
2877
  * as long as the binding is still empty.
2878
+ * @param {boolean} [bKeepCreated]
2879
+ * Whether created contexts shall remain in aContexts
2775
2880
  *
2776
2881
  * @private
2777
2882
  */
2778
- ODataListBinding.prototype.reset = function (sChangeReason) {
2883
+ ODataListBinding.prototype.reset = function (sChangeReason, bKeepCreated) {
2779
2884
  var bEmpty = this.iCurrentEnd === 0,
2780
2885
  that = this;
2781
2886
 
2887
+ if (!bKeepCreated) {
2888
+ this.iCreatedContexts = 0; // number of (client-side) created contexts in aContexts
2889
+ // true if contexts have been created at the end, false if contexts have been created at
2890
+ // the start, undefined if there are no created contexts
2891
+ this.bCreatedAtEnd = undefined;
2892
+ }
2782
2893
  if (this.aContexts) { // allow initial call from c'tor via #applyParameters
2783
- this.aContexts.forEach(function (oContext) {
2894
+ this.aContexts.slice(this.iCreatedContexts).forEach(function (oContext) {
2784
2895
  that.mPreviousContextsByPath[oContext.getPath()] = oContext;
2785
2896
  });
2897
+ this.aContexts.length = this.iCreatedContexts;
2898
+ } else {
2899
+ this.aContexts = [];
2786
2900
  }
2787
- this.aContexts = [];
2788
- this.iCreatedContexts = 0; // number of (client-side) created contexts in aContexts
2789
- // true if contexts have been created at the end, false if contexts have been created at the
2790
- // start, undefined if there are no created contexts
2791
- this.bCreatedAtEnd = undefined;
2792
2901
  // the range of array indices for getCurrentContexts
2793
2902
  this.iCurrentBegin = this.iCurrentEnd = 0;
2794
2903
  // upper boundary for server-side list length (based on observations so far)
@@ -2846,7 +2955,8 @@ sap.ui.define([
2846
2955
  aBindings.forEach(function (oDependentBinding) {
2847
2956
  // do not call checkUpdate in dependent property bindings if the cache of this
2848
2957
  // binding is reset and the binding has not yet fired a change event
2849
- oDependentBinding.resumeInternal(!bRefresh, !!sResumeChangeReason);
2958
+ oDependentBinding.resumeInternal(!bRefresh,
2959
+ !!sResumeChangeReason && !oDependentBinding.oContext.isKeepAlive());
2850
2960
  });
2851
2961
  if (this.sChangeReason === "AddVirtualContext") {
2852
2962
  // In a refresh event the table would ignore the result -> no virtual context -> no
@@ -2931,10 +3041,13 @@ sap.ui.define([
2931
3041
  * separate row after all children, when a group level node is expanded (since 1.86.0);
2932
3042
  * <code>true</code> for bottom only, <code>false</code> for top and bottom, the default is
2933
3043
  * top only (that is, as part of the group level node)
2934
- * @throws {Error}
2935
- * If the given data aggregation object is unsupported, if the system query option
2936
- * <code>$apply</code> has been specified explicitly before, or if there are pending changes
2937
- *
3044
+ * @throws {Error} If
3045
+ * <ul>
3046
+ * <li> the given data aggregation object is unsupported,
3047
+ * <li> the <code>$apply</code> system query option has been specified explicitly before,
3048
+ * <li> the binding has a kept-alive context,
3049
+ * <li> there are pending changes
3050
+ * </ul>
2938
3051
  * @example <caption>First group level is product category including subtotals for the net
2939
3052
  * amount in display currency. On leaf level, transaction currency is used as an additional
2940
3053
  * dimension and the net amount is averaged.</caption>
@@ -2960,9 +3073,19 @@ sap.ui.define([
2960
3073
  ODataListBinding.prototype.setAggregation = function (oAggregation) {
2961
3074
  var mParameters;
2962
3075
 
3076
+ function hasKeptAliveContext(aContexts) {
3077
+ return aContexts.some(function (oContext) {
3078
+ return oContext && oContext.isKeepAlive();
3079
+ });
3080
+ }
3081
+
2963
3082
  if (this.hasPendingChanges()) {
2964
3083
  throw new Error("Cannot set $$aggregation due to pending changes");
2965
3084
  }
3085
+ if (hasKeptAliveContext(this.aContexts)
3086
+ || hasKeptAliveContext(Object.values(this.mPreviousContextsByPath))) {
3087
+ throw new Error("Cannot set $$aggregation due to a kept-alive context");
3088
+ }
2966
3089
 
2967
3090
  mParameters = Object.assign({}, this.mParameters);
2968
3091
  if (oAggregation === undefined) {
@@ -3048,10 +3171,11 @@ sap.ui.define([
3048
3171
  /**
3049
3172
  * Sort the entries represented by this list binding according to the given sorters.
3050
3173
  * The sorters are stored at this list binding and they are used for each following data
3051
- * request.
3174
+ * request. Since 1.97.0, if sorters are unchanged, no request is sent, regardless of pending
3175
+ * changes.
3052
3176
  *
3053
- * If there are pending changes an error is thrown. Use {@link #hasPendingChanges} to check if
3054
- * there are pending changes. If there are changes, call
3177
+ * If there are pending changes that cannot be ignored, an error is thrown. Use
3178
+ * {@link #hasPendingChanges} to check if there are such pending changes. If there are, call
3055
3179
  * {@link sap.ui.model.odata.v4.ODataModel#submitBatch} to submit the changes or
3056
3180
  * {@link sap.ui.model.odata.v4.ODataModel#resetChanges} to reset the changes before calling
3057
3181
  * {@link #sort}.
@@ -3064,8 +3188,10 @@ sap.ui.define([
3064
3188
  * @returns {this}
3065
3189
  * <code>this</code> to facilitate method chaining
3066
3190
  * @throws {Error}
3067
- * If there are pending changes or if an unsupported operation mode is used (see
3068
- * {@link sap.ui.model.odata.v4.ODataModel#bindList}).
3191
+ * If there are pending changes that cannot be ignored or if an unsupported operation mode is
3192
+ * used (see {@link sap.ui.model.odata.v4.ODataModel#bindList}). Since 1.97.0, pending changes
3193
+ * are ignored if they relate to a
3194
+ * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding.
3069
3195
  *
3070
3196
  * @public
3071
3197
  * @see sap.ui.model.ListBinding#sort
@@ -3073,14 +3199,21 @@ sap.ui.define([
3073
3199
  */
3074
3200
  // @override sap.ui.model.ListBinding#sort
3075
3201
  ODataListBinding.prototype.sort = function (vSorters) {
3202
+ var aSorters = _Helper.toArray(vSorters);
3203
+
3076
3204
  if (this.sOperationMode !== OperationMode.Server) {
3077
3205
  throw new Error("Operation mode has to be sap.ui.model.odata.OperationMode.Server");
3078
3206
  }
3079
- if (this.hasPendingChanges()) {
3207
+
3208
+ if (_Helper.deepEqual(aSorters, this.aSorters)) {
3209
+ return this;
3210
+ }
3211
+
3212
+ if (this.hasPendingChanges(true)) {
3080
3213
  throw new Error("Cannot sort due to pending changes");
3081
3214
  }
3082
3215
 
3083
- this.aSorters = _Helper.toArray(vSorters);
3216
+ this.aSorters = aSorters;
3084
3217
 
3085
3218
  if (this.isRootBindingSuspended()) {
3086
3219
  this.setResumeChangeReason(ChangeReason.Sort);
@@ -658,7 +658,7 @@ sap.ui.define([
658
658
  * @hideconstructor
659
659
  * @public
660
660
  * @since 1.37.0
661
- * @version 1.96.2
661
+ * @version 1.97.0
662
662
  */
663
663
  var ODataMetaModel = MetaModel.extend("sap.ui.model.odata.v4.ODataMetaModel", {
664
664
  /*
@@ -210,7 +210,7 @@ sap.ui.define([
210
210
  * @extends sap.ui.model.Model
211
211
  * @public
212
212
  * @since 1.37.0
213
- * @version 1.96.2
213
+ * @version 1.97.0
214
214
  */
215
215
  var ODataModel = Model.extend("sap.ui.model.odata.v4.ODataModel",
216
216
  /** @lends sap.ui.model.odata.v4.ODataModel.prototype */
@@ -1184,6 +1184,7 @@ sap.ui.define([
1184
1184
  *
1185
1185
  * @private
1186
1186
  */
1187
+ // eslint-disable-next-line valid-jsdoc -- .@$ui5. is not understood properly
1187
1188
  ODataModel.prototype.createUI5Message = function (oRawMessage, sResourcePath, sCachePath) {
1188
1189
  var bIsBound = typeof oRawMessage.target === "string",
1189
1190
  sMessageLongtextUrl = oRawMessage.longtextUrl,
@@ -299,8 +299,8 @@ sap.ui.define([
299
299
  /**
300
300
  * Changes this binding's parameters and refreshes the binding.
301
301
  *
302
- * If there are pending changes an error is thrown. Use {@link #hasPendingChanges} to check if
303
- * there are pending changes. If there are changes, call
302
+ * If there are pending changes that cannot be ignored, an error is thrown. Use
303
+ * {@link #hasPendingChanges} to check if there are such pending changes. If there are, call
304
304
  * {@link sap.ui.model.odata.v4.ODataModel#submitBatch} to submit the changes or
305
305
  * {@link sap.ui.model.odata.v4.ODataModel#resetChanges} to reset the changes before calling
306
306
  * {@link #changeParameters}.
@@ -313,12 +313,14 @@ sap.ui.define([
313
313
  * Map of binding parameters, see {@link sap.ui.model.odata.v4.ODataModel#bindList} and
314
314
  * {@link sap.ui.model.odata.v4.ODataModel#bindContext}
315
315
  * @throws {Error}
316
- * If there are pending changes or if <code>mParameters</code> is missing, contains
317
- * binding-specific or unsupported parameters, contains unsupported values, or contains the
318
- * property "$expand" or "$select" when the model is in auto-$expand/$select mode.
319
- * Since 1.90.0, binding-specific parameters are ignored if they are unchanged. Since 1.93.0,
320
- * string values for "$expand" and "$select" are ignored if they are unchanged; pending
321
- * changes are ignored if all parameters are unchanged.
316
+ * If there are pending changes that cannot be ignored or if <code>mParameters</code> is
317
+ * missing, contains binding-specific or unsupported parameters, contains unsupported values,
318
+ * or contains the property "$expand" or "$select" when the model is in auto-$expand/$select
319
+ * mode. Since 1.90.0, binding-specific parameters are ignored if they are unchanged. Since
320
+ * 1.93.0, string values for "$expand" and "$select" are ignored if they are unchanged;
321
+ * pending changes are ignored if all parameters are unchanged. Since 1.97.0, pending changes
322
+ * are ignored if they relate to a
323
+ * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding.
322
324
  *
323
325
  * @public
324
326
  * @since 1.45.0
@@ -384,7 +386,7 @@ sap.ui.define([
384
386
  }
385
387
 
386
388
  if (sChangeReason) {
387
- if (this.hasPendingChanges()) {
389
+ if (this.hasPendingChanges(true)) {
388
390
  throw new Error("Cannot change parameters due to pending changes");
389
391
  }
390
392
  this.applyParameters(mBindingParameters, sChangeReason);
@@ -456,7 +458,7 @@ sap.ui.define([
456
458
  * The absolute path to the collection in the cache where to create the entity
457
459
  * @param {string} sTransientPredicate
458
460
  * A (temporary) key predicate for the transient entity: "($uid=...)"
459
- * @param {object} oInitialData
461
+ * @param {object} [oInitialData={}]
460
462
  * The initial data for the created entity
461
463
  * @param {function} fnErrorCallback
462
464
  * A function which is called with an error object each time a POST request for the create
@@ -574,6 +576,10 @@ sap.ui.define([
574
576
  * An entity with the ETag of the binding for which the deletion was requested. This is
575
577
  * provided if the deletion is delegated from a context binding with empty path to a list
576
578
  * binding.
579
+ * @param {boolean} [bDoNotRequestCount]
580
+ * Whether not to request the new count from the server; useful in case of
581
+ * {@link sap.ui.model.odata.v4.Context#replaceWith} where it is known that the count remains
582
+ * unchanged
577
583
  * @param {function} fnCallback
578
584
  * A function which is called after the entity has been deleted from the server and from the
579
585
  * cache; the index of the entity is passed as parameter
@@ -587,7 +593,7 @@ sap.ui.define([
587
593
  * @private
588
594
  */
589
595
  ODataParentBinding.prototype.deleteFromCache = function (oGroupLock, sEditUrl, sPath,
590
- oETagEntity, fnCallback) {
596
+ oETagEntity, bDoNotRequestCount, fnCallback) {
591
597
  var sGroupId;
592
598
 
593
599
  if (this.oCache === undefined) {
@@ -599,10 +605,12 @@ sap.ui.define([
599
605
  if (!this.oModel.isAutoGroup(sGroupId) && !this.oModel.isDirectGroup(sGroupId)) {
600
606
  throw new Error("Illegal update group ID: " + sGroupId);
601
607
  }
602
- return this.oCache._delete(oGroupLock, sEditUrl, sPath, oETagEntity, fnCallback);
608
+ return this.oCache._delete(oGroupLock, sEditUrl, sPath, oETagEntity, bDoNotRequestCount,
609
+ fnCallback);
603
610
  }
604
611
  return this.oContext.getBinding().deleteFromCache(oGroupLock, sEditUrl,
605
- _Helper.buildPath(this.oContext.iIndex, this.sPath, sPath), oETagEntity, fnCallback);
612
+ _Helper.buildPath(this.oContext.iIndex, this.sPath, sPath), oETagEntity,
613
+ bDoNotRequestCount, fnCallback);
606
614
  };
607
615
 
608
616
  /**
@@ -992,13 +1000,14 @@ sap.ui.define([
992
1000
  * @override
993
1001
  * @see sap.ui.model.odata.v4.ODataBinding#hasPendingChangesInDependents
994
1002
  */
995
- ODataParentBinding.prototype.hasPendingChangesInDependents = function () {
996
- var aDependents = this.getDependentBindings();
997
-
998
- return aDependents.some(function (oDependent) {
1003
+ ODataParentBinding.prototype.hasPendingChangesInDependents = function (bIgnoreKeptAlive) {
1004
+ return this.getDependentBindings().some(function (oDependent) {
999
1005
  var oCache = oDependent.oCache,
1000
1006
  bHasPendingChanges;
1001
1007
 
1008
+ if (bIgnoreKeptAlive && oDependent.oContext.isKeepAlive()) {
1009
+ return false;
1010
+ }
1002
1011
  if (oCache !== undefined) {
1003
1012
  // Pending changes for this cache are only possible when there is a cache already
1004
1013
  if (oCache && oCache.hasPendingChangesForPath("")) {
@@ -1010,7 +1019,10 @@ sap.ui.define([
1010
1019
  if (oDependent.mCacheByResourcePath) {
1011
1020
  bHasPendingChanges = Object.keys(oDependent.mCacheByResourcePath)
1012
1021
  .some(function (sPath) {
1013
- return oDependent.mCacheByResourcePath[sPath].hasPendingChangesForPath("");
1022
+ var oCacheForPath = oDependent.mCacheByResourcePath[sPath];
1023
+
1024
+ return oCacheForPath !== oCache // don't ask again
1025
+ && oCacheForPath.hasPendingChangesForPath("");
1014
1026
  });
1015
1027
  if (bHasPendingChanges) {
1016
1028
  return true;
@@ -1322,8 +1334,10 @@ sap.ui.define([
1322
1334
 
1323
1335
  /**
1324
1336
  * Suspends this binding. A suspended binding does not fire change events nor does it trigger
1325
- * data service requests. Call {@link #resume} to resume the binding.
1326
- * Before 1.53.0, this method was not supported and threw an error.
1337
+ * data service requests. Call {@link #resume} to resume the binding. Before 1.53.0, this method
1338
+ * was not supported and threw an error. Since 1.97.0, pending changes are ignored if they
1339
+ * relate to a {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this
1340
+ * binding.
1327
1341
  *
1328
1342
  * @throws {Error}
1329
1343
  * If this binding
@@ -1331,7 +1345,7 @@ sap.ui.define([
1331
1345
  * <li>is relative to a {@link sap.ui.model.odata.v4.Context},</li>
1332
1346
  * <li>is an operation binding,</li>
1333
1347
  * <li>has {@link sap.ui.model.Binding#isSuspended} set to <code>true</code>,</li>
1334
- * <li>has pending changes,</li>
1348
+ * <li>has pending changes that cannot be ignored,</li>
1335
1349
  * <li>is not a root binding. Use {@link #getRootBinding} to determine the root binding.</li>
1336
1350
  * </ul>
1337
1351
  *
@@ -1356,7 +1370,7 @@ sap.ui.define([
1356
1370
  if (this.bSuspended) {
1357
1371
  throw new Error("Cannot suspend a suspended binding: " + this);
1358
1372
  }
1359
- if (this.hasPendingChanges()) {
1373
+ if (this.hasPendingChanges(true)) {
1360
1374
  throw new Error("Cannot suspend a binding with pending changes: " + this);
1361
1375
  }
1362
1376
 
@@ -1445,7 +1459,6 @@ sap.ui.define([
1445
1459
  "adjustPredicate",
1446
1460
  "destroy",
1447
1461
  "doDeregisterChangeListener",
1448
- "fetchCache",
1449
1462
  "getGeneration",
1450
1463
  "hasPendingChangesForPath"
1451
1464
  ].forEach(function (sMethod) { // method (still) not final, allow for "super" calls