@openui5/sap.ui.core 1.105.0 → 1.106.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 (314) hide show
  1. package/.reuse/dep5 +20 -17
  2. package/THIRDPARTY.txt +31 -21
  3. package/package.json +1 -1
  4. package/src/jquery.sap.dom.js +10 -10
  5. package/src/jquery.sap.global.js +24 -216
  6. package/src/jquery.sap.history.js +1 -1
  7. package/src/jquery.sap.properties.js +2 -2
  8. package/src/jquery.sap.resources.js +1 -1
  9. package/src/jquery.sap.script.js +1 -1
  10. package/src/jquery.sap.storage.js +4 -4
  11. package/src/sap/base/i18n/ResourceBundle.js +7 -11
  12. package/src/sap/base/util/ObjectPath.js +1 -1
  13. package/src/sap/base/util/Properties.js +1 -1
  14. package/src/sap/base/util/fetch.js +8 -10
  15. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  16. package/src/sap/base/util/restricted/_castArray.js +1 -1
  17. package/src/sap/base/util/restricted/_compact.js +1 -1
  18. package/src/sap/base/util/restricted/_curry.js +1 -1
  19. package/src/sap/base/util/restricted/_debounce.js +1 -1
  20. package/src/sap/base/util/restricted/_difference.js +1 -1
  21. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  22. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  23. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  24. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  25. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  26. package/src/sap/base/util/restricted/_flatten.js +1 -1
  27. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  28. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  29. package/src/sap/base/util/restricted/_intersection.js +1 -1
  30. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  31. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  32. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  33. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  34. package/src/sap/base/util/restricted/_isNil.js +1 -1
  35. package/src/sap/base/util/restricted/_max.js +1 -1
  36. package/src/sap/base/util/restricted/_merge.js +1 -1
  37. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  38. package/src/sap/base/util/restricted/_min.js +1 -1
  39. package/src/sap/base/util/restricted/_omit.js +1 -1
  40. package/src/sap/base/util/restricted/_pick.js +1 -1
  41. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  42. package/src/sap/base/util/restricted/_throttle.js +1 -1
  43. package/src/sap/base/util/restricted/_toArray.js +1 -1
  44. package/src/sap/base/util/restricted/_union.js +1 -1
  45. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  46. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  47. package/src/sap/base/util/restricted/_uniq.js +1 -1
  48. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  49. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  50. package/src/sap/base/util/restricted/_without.js +1 -1
  51. package/src/sap/base/util/restricted/_xor.js +1 -1
  52. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  53. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  54. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  55. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  56. package/src/sap/base/util/syncFetch.js +9 -16
  57. package/src/sap/ui/Device.js +3 -3
  58. package/src/sap/ui/Global.js +7 -14
  59. package/src/sap/ui/VersionInfo.js +57 -54
  60. package/src/sap/ui/base/BindingInfo.js +198 -0
  61. package/src/sap/ui/base/DataType.js +1 -1
  62. package/src/sap/ui/base/Event.js +2 -2
  63. package/src/sap/ui/base/EventProvider.js +2 -2
  64. package/src/sap/ui/base/Interface.js +1 -1
  65. package/src/sap/ui/base/ManagedObject.js +209 -979
  66. package/src/sap/ui/base/ManagedObjectMetadata.js +6 -6
  67. package/src/sap/ui/base/Metadata.js +1 -1
  68. package/src/sap/ui/base/Object.js +1 -1
  69. package/src/sap/ui/base/ObjectPool.js +1 -1
  70. package/src/sap/ui/core/.library +13 -9
  71. package/src/sap/ui/core/BusyIndicator.js +1 -1
  72. package/src/sap/ui/core/Component.js +5 -5
  73. package/src/sap/ui/core/ComponentContainer.js +1 -1
  74. package/src/sap/ui/core/ComponentMetadata.js +5 -12
  75. package/src/sap/ui/core/ComponentSupport.js +1 -1
  76. package/src/sap/ui/core/Configuration.js +525 -336
  77. package/src/sap/ui/core/Control.js +1 -1
  78. package/src/sap/ui/core/Core.js +78 -125
  79. package/src/sap/ui/core/CustomData.js +1 -1
  80. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  81. package/src/sap/ui/core/Element.js +60 -4
  82. package/src/sap/ui/core/ElementMetadata.js +1 -1
  83. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  84. package/src/sap/ui/core/EventBus.js +1 -1
  85. package/src/sap/ui/core/FocusHandler.js +29 -7
  86. package/src/sap/ui/core/Fragment.js +1 -1
  87. package/src/sap/ui/core/HTML.js +1 -1
  88. package/src/sap/ui/core/History.js +1 -1
  89. package/src/sap/ui/core/Icon.js +1 -1
  90. package/src/sap/ui/core/IconPool.js +8 -8
  91. package/src/sap/ui/core/IndicationColorSupport.js +2 -2
  92. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  93. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  94. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  95. package/src/sap/ui/core/InvisibleText.js +1 -1
  96. package/src/sap/ui/core/Item.js +1 -1
  97. package/src/sap/ui/core/LabelEnablement.js +1 -1
  98. package/src/sap/ui/core/LayoutData.js +1 -1
  99. package/src/sap/ui/core/ListItem.js +1 -1
  100. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  101. package/src/sap/ui/core/Locale.js +1 -1
  102. package/src/sap/ui/core/LocaleData.js +5 -5
  103. package/src/sap/ui/core/Manifest.js +1 -1
  104. package/src/sap/ui/core/Message.js +1 -1
  105. package/src/sap/ui/core/Popup.js +13 -8
  106. package/src/sap/ui/core/RenderManager.js +7 -1
  107. package/src/sap/ui/core/Renderer.js +1 -1
  108. package/src/sap/ui/core/ResizeHandler.js +7 -7
  109. package/src/sap/ui/core/ScrollBar.js +1 -1
  110. package/src/sap/ui/core/SeparatorItem.js +1 -1
  111. package/src/sap/ui/core/Title.js +1 -1
  112. package/src/sap/ui/core/TooltipBase.js +12 -13
  113. package/src/sap/ui/core/UIArea.js +8 -9
  114. package/src/sap/ui/core/UIComponent.js +3 -3
  115. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  116. package/src/sap/ui/core/ValueStateSupport.js +2 -2
  117. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  118. package/src/sap/ui/core/XMLComposite.js +2 -2
  119. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  120. package/src/sap/ui/core/XMLTemplateProcessor.js +7 -7
  121. package/src/sap/ui/core/_ConfigurationProvider.js +187 -0
  122. package/src/sap/ui/core/cache/CacheManager.js +2 -2
  123. package/src/sap/ui/core/cldr/es_BO.json +3 -3
  124. package/src/sap/ui/core/cldr/es_CL.json +3 -3
  125. package/src/sap/ui/core/cldr/es_MX.json +3 -3
  126. package/src/sap/ui/core/cldr/es_PE.json +3 -3
  127. package/src/sap/ui/core/cldr/es_UY.json +3 -3
  128. package/src/sap/ui/core/cldr/es_VE.json +2 -2
  129. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  130. package/src/sap/ui/core/delegate/ScrollEnablement.js +7 -6
  131. package/src/sap/ui/core/dnd/DragAndDrop.js +13 -9
  132. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  133. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  134. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  135. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  136. package/src/sap/ui/core/format/DateFormat.js +5 -0
  137. package/src/sap/ui/core/format/NumberFormat.js +1 -1
  138. package/src/sap/ui/core/format/TimezoneUtil.js +1 -1
  139. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  140. package/src/sap/ui/core/library.js +3 -3
  141. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  142. package/src/sap/ui/core/message/Message.js +1 -1
  143. package/src/sap/ui/core/message/MessageManager.js +1 -1
  144. package/src/sap/ui/core/message/MessageParser.js +1 -1
  145. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  146. package/src/sap/ui/core/mvc/Controller.js +5 -0
  147. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  148. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  149. package/src/sap/ui/core/mvc/JSView.js +2 -2
  150. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  151. package/src/sap/ui/core/mvc/View.js +1 -1
  152. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  153. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  154. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  155. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  156. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  157. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  158. package/src/sap/ui/core/routing/Router.js +1 -1
  159. package/src/sap/ui/core/rules/App.support.js +11 -13
  160. package/src/sap/ui/core/rules/Config.support.js +13 -13
  161. package/src/sap/ui/core/rules/CoreHelper.support.js +3 -3
  162. package/src/sap/ui/core/rules/Model.support.js +8 -8
  163. package/src/sap/ui/core/rules/Rendering.support.js +1 -1
  164. package/src/sap/ui/core/rules/Theming.support.js +8 -8
  165. package/src/sap/ui/core/rules/View.support.js +9 -9
  166. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  167. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  168. package/src/sap/ui/core/service/Service.js +1 -1
  169. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  170. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  171. package/src/sap/ui/core/support/Hotkeys.js +2 -3
  172. package/src/sap/ui/core/support/Plugin.js +1 -1
  173. package/src/sap/ui/core/support/Support.js +1 -1
  174. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  175. package/src/sap/ui/core/support/plugins/Debugging.js +3 -3
  176. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  177. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  178. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  179. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  180. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  181. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  182. package/src/sap/ui/core/support/plugins/ViewInfo.js +2 -2
  183. package/src/sap/ui/core/support/support.html +1 -1
  184. package/src/sap/ui/core/support/techinfo/TechnicalInfo.js +3 -3
  185. package/src/sap/ui/core/themes/base/shared.less +6 -0
  186. package/src/sap/ui/core/theming/Parameters.js +8 -15
  187. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  188. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  189. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  190. package/src/sap/ui/core/tmpl/Template.js +6 -4
  191. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  192. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  193. package/src/sap/ui/core/util/Export.js +1 -1
  194. package/src/sap/ui/core/util/ExportCell.js +1 -1
  195. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  196. package/src/sap/ui/core/util/ExportRow.js +1 -1
  197. package/src/sap/ui/core/util/ExportType.js +1 -1
  198. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  199. package/src/sap/ui/core/util/File.js +1 -1
  200. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  201. package/src/sap/ui/core/util/MockServer.js +45 -71
  202. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  203. package/src/sap/ui/core/util/ResponsivePaddingsEnablement.js +4 -3
  204. package/src/sap/ui/core/util/XMLPreprocessor.js +2 -2
  205. package/src/sap/ui/core/util/reflection/BaseTreeModifier.js +1 -1
  206. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  207. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  208. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  209. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  210. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  211. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  212. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  213. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  214. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  215. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  216. package/src/sap/ui/debug/ControlTree.js +1 -1
  217. package/src/sap/ui/debug/DebugEnv.js +1 -1
  218. package/src/sap/ui/debug/PropertyList.css +1 -31
  219. package/src/sap/ui/debug/PropertyList.js +6 -250
  220. package/src/sap/ui/dom/getScrollbarSize.js +1 -1
  221. package/src/sap/ui/dom/jquery/control.js +1 -0
  222. package/src/sap/ui/events/jquery/EventSimulation.js +4 -4
  223. package/src/sap/ui/model/ClientModel.js +1 -1
  224. package/src/sap/ui/model/CompositeDataState.js +1 -1
  225. package/src/sap/ui/model/CompositeType.js +1 -1
  226. package/src/sap/ui/model/Context.js +3 -0
  227. package/src/sap/ui/model/ContextBinding.js +1 -1
  228. package/src/sap/ui/model/DataState.js +2 -2
  229. package/src/sap/ui/model/ListBinding.js +2 -2
  230. package/src/sap/ui/model/ManagedObjectBindingSupport.js +871 -0
  231. package/src/sap/ui/model/MetaModel.js +1 -1
  232. package/src/sap/ui/model/Model.js +16 -5
  233. package/src/sap/ui/model/SelectionModel.js +1 -1
  234. package/src/sap/ui/model/SimpleType.js +2 -2
  235. package/src/sap/ui/model/Sorter.js +2 -2
  236. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  237. package/src/sap/ui/model/Type.js +1 -1
  238. package/src/sap/ui/model/json/JSONModel.js +2 -2
  239. package/src/sap/ui/model/message/MessageModel.js +1 -1
  240. package/src/sap/ui/model/odata/AnnotationHelper.js +4 -4
  241. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  242. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  243. package/src/sap/ui/model/odata/ODataMetaModel.js +10 -10
  244. package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
  245. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  246. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +22 -29
  247. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  248. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  249. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  250. package/src/sap/ui/model/odata/type/Date.js +1 -1
  251. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  252. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  253. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  254. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +1 -1
  255. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  256. package/src/sap/ui/model/odata/type/Double.js +1 -1
  257. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  258. package/src/sap/ui/model/odata/type/Int.js +1 -1
  259. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  260. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  261. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  262. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  263. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  264. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  265. package/src/sap/ui/model/odata/type/Single.js +1 -1
  266. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  267. package/src/sap/ui/model/odata/type/String.js +1 -1
  268. package/src/sap/ui/model/odata/type/Time.js +1 -1
  269. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  270. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  271. package/src/sap/ui/model/odata/v2/Context.js +5 -5
  272. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  273. package/src/sap/ui/model/odata/v2/ODataContextBinding.js +1 -1
  274. package/src/sap/ui/model/odata/v2/ODataListBinding.js +1 -1
  275. package/src/sap/ui/model/odata/v2/ODataModel.js +4 -4
  276. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +1 -1
  277. package/src/sap/ui/model/odata/v4/AnnotationHelper.js +3 -3
  278. package/src/sap/ui/model/odata/v4/Context.js +88 -54
  279. package/src/sap/ui/model/odata/v4/ODataBinding.js +47 -4
  280. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +86 -66
  281. package/src/sap/ui/model/odata/v4/ODataListBinding.js +96 -68
  282. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +13 -10
  283. package/src/sap/ui/model/odata/v4/ODataModel.js +247 -27
  284. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +23 -5
  285. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +14 -8
  286. package/src/sap/ui/model/odata/v4/ODataUtils.js +7 -4
  287. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +8 -8
  288. package/src/sap/ui/model/odata/v4/lib/_AggregationHelper.js +40 -6
  289. package/src/sap/ui/model/odata/v4/lib/_Cache.js +89 -69
  290. package/src/sap/ui/model/odata/v4/lib/_ConcatHelper.js +2 -3
  291. package/src/sap/ui/model/odata/v4/lib/_Helper.js +47 -35
  292. package/src/sap/ui/model/odata/v4/lib/_MinMaxHelper.js +2 -3
  293. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +5 -0
  294. package/src/sap/ui/model/resource/ResourceModel.js +2 -2
  295. package/src/sap/ui/model/type/Boolean.js +1 -1
  296. package/src/sap/ui/model/type/Currency.js +2 -2
  297. package/src/sap/ui/model/type/Date.js +1 -1
  298. package/src/sap/ui/model/type/DateInterval.js +1 -1
  299. package/src/sap/ui/model/type/DateTime.js +1 -1
  300. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  301. package/src/sap/ui/model/type/FileSize.js +1 -1
  302. package/src/sap/ui/model/type/Float.js +1 -1
  303. package/src/sap/ui/model/type/Integer.js +1 -1
  304. package/src/sap/ui/model/type/String.js +2 -2
  305. package/src/sap/ui/model/type/Time.js +1 -1
  306. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  307. package/src/sap/ui/model/type/Unit.js +1 -1
  308. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  309. package/src/sap/ui/qunit/QUnitUtils.js +1 -2
  310. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  311. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  312. package/src/sap/ui/test/OpaBuilder.js +1 -1
  313. package/src/sap/ui/test/generic/TestBase.js +1 -1
  314. package/src/sap/ui/util/Storage.js +1 -1
@@ -6,20 +6,11 @@
6
6
 
7
7
  // Provides the base class for all objects with managed properties and aggregations.
8
8
  sap.ui.define([
9
- './BindingParser',
10
- './DataType',
11
- './EventProvider',
12
- './ManagedObjectMetadata',
13
- './Object',
14
- '../model/BindingMode',
15
- '../model/StaticBinding',
16
- '../model/CompositeBinding',
17
- '../model/Context',
18
- '../model/FormatException',
19
- '../model/ParseException',
20
- '../model/Type',
21
- '../model/ValidateException',
22
- "sap/ui/base/SyncPromise",
9
+ "./DataType",
10
+ "./EventProvider",
11
+ "./ManagedObjectMetadata",
12
+ "./Object",
13
+ "./BindingInfo",
23
14
  "sap/ui/util/ActivityDetection",
24
15
  "sap/base/util/ObjectPath",
25
16
  "sap/base/Log",
@@ -30,20 +21,11 @@ sap.ui.define([
30
21
  "sap/base/util/extend",
31
22
  "sap/base/util/isEmptyObject"
32
23
  ], function(
33
- BindingParser,
34
24
  DataType,
35
25
  EventProvider,
36
26
  ManagedObjectMetadata,
37
27
  BaseObject,
38
- BindingMode,
39
- StaticBinding,
40
- CompositeBinding,
41
- Context,
42
- FormatException,
43
- ParseException,
44
- Type,
45
- ValidateException,
46
- SyncPromise,
28
+ BindingInfo,
47
29
  ActivityDetection,
48
30
  ObjectPath,
49
31
  Log,
@@ -266,7 +248,7 @@ sap.ui.define([
266
248
  *
267
249
  * @extends sap.ui.base.EventProvider
268
250
  * @author SAP SE
269
- * @version 1.105.0
251
+ * @version 1.106.0
270
252
  * @public
271
253
  * @alias sap.ui.base.ManagedObject
272
254
  */
@@ -556,8 +538,42 @@ sap.ui.define([
556
538
 
557
539
  }, /* Metadata constructor */ ManagedObjectMetadata);
558
540
 
559
- // Marker to not 'forget' ui5Objects
560
- var sUI5ObjectMarker = Symbol("ui5object");
541
+ // The current BindingParser implementation is exposed via "ManagedObject.bindingParser".
542
+ // This is used in tests for switching the BindingParser implementation on the fly.
543
+ // We delegate any changes to this property back to the BindingInfo.
544
+ Object.defineProperty(ManagedObject, "bindingParser", {
545
+ set: function(v) {
546
+ BindingInfo.parse = v;
547
+ },
548
+ get: function() {
549
+ return BindingInfo.parse;
550
+ }
551
+ });
552
+
553
+ function assertModelName(sModelName) {
554
+ assert(sModelName === undefined || (typeof sModelName === "string" && !/^(undefined|null)?$/.test(sModelName)), "sModelName must be a string or omitted");
555
+ }
556
+
557
+ // Binding support Marker
558
+ var _bHasBindingSupport = false;
559
+
560
+ /**
561
+ * Checks if the <code>ManagedObjectBindingSupport</code> mixin is introduced
562
+ * via a model instance.
563
+ * If so, it is applied to the <code>ManagedObject.prototype</code> once.
564
+ *
565
+ * @param {Object<string, sap.ui.model.Model>} mModels a map of models, keyed by the model name.
566
+ */
567
+ function checkForBindingSupport(mModels) {
568
+ if (!_bHasBindingSupport ) {
569
+ var oModel = Object.values(mModels)[0];
570
+ // In theory an application could pass an object that does not extend from sap.ui.model.Model
571
+ if (oModel && oModel.mixinBindingSupport) {
572
+ oModel.mixinBindingSupport(ManagedObject.prototype);
573
+ _bHasBindingSupport = true;
574
+ }
575
+ }
576
+ }
561
577
 
562
578
  /**
563
579
  * Returns the metadata for the ManagedObject class.
@@ -600,7 +616,7 @@ sap.ui.define([
600
616
  *
601
617
  * Example:
602
618
  * <pre>
603
- * ManagedObect.extend('sap.mylib.MyClass', {
619
+ * ManagedObject.extend('sap.mylib.MyClass', {
604
620
  * metadata : {
605
621
  * library: 'sap.mylib',
606
622
  * properties : {
@@ -1117,7 +1133,8 @@ sap.ui.define([
1117
1133
  if ( typeof mSettings.bindingContexts !== "object" ) {
1118
1134
  throw new Error("bindingContexts must be a simple object");
1119
1135
  }
1120
- if ( mSettings.bindingContexts instanceof Context) {
1136
+ var oBindingContexts = mSettings.bindingContexts;
1137
+ if ( BaseObject.isA(oBindingContexts, "sap.ui.model.Context")) {
1121
1138
  this.setBindingContext(mSettings.bindingContexts);
1122
1139
  } else {
1123
1140
  for (sKey in mSettings.bindingContexts ) {
@@ -1235,7 +1252,7 @@ sap.ui.define([
1235
1252
  * @public
1236
1253
  */
1237
1254
  ManagedObject.escapeSettingsValue = function(vValue) {
1238
- return (typeof vValue === "string") ? ManagedObject.bindingParser.escape(vValue) : vValue;
1255
+ return (typeof vValue === "string") ? BindingInfo.escape(vValue) : vValue;
1239
1256
  };
1240
1257
 
1241
1258
  /**
@@ -1612,9 +1629,9 @@ sap.ui.define([
1612
1629
  * Use the concrete method get<i>XYZ</i> for association 'XYZ' instead.
1613
1630
  *
1614
1631
  * @param {string} sAssociationName the name of the association
1615
- * @param {object}
1616
- * oDefaultForCreation the object that is used in case the current aggregation is empty (only null or empty array allowed)
1617
- * @return {string | string[]} the ID of the associated managed object or an array of such IDs; may be null if the association has not been populated
1632
+ * @param {object} oDefaultForCreation
1633
+ * the object that is used in case the current aggregation is empty (only null or empty array allowed)
1634
+ * @returns {string | string[] | null} the ID of the associated managed object or an array of such IDs; may be null if the association has not been populated
1618
1635
  * @protected
1619
1636
  */
1620
1637
  ManagedObject.prototype.getAssociation = function(sAssociationName, oDefaultForCreation) {
@@ -1855,7 +1872,7 @@ sap.ui.define([
1855
1872
  return oObject;
1856
1873
  }
1857
1874
 
1858
- if ( oObject instanceof BaseObject && oObject.isA(oAggregation.type) ) {
1875
+ if ( BaseObject.isA(oObject, oAggregation.type) ) {
1859
1876
  return oObject;
1860
1877
  }
1861
1878
 
@@ -2763,7 +2780,7 @@ sap.ui.define([
2763
2780
  *
2764
2781
  * <b>Note: </b> There is no API to determine the original API parent.
2765
2782
  *
2766
- * @return {sap.ui.base.ManagedObject} The technical parent managed object or <code>null</code>
2783
+ * @returns {sap.ui.base.ManagedObject|null} The technical parent managed object or <code>null</code>
2767
2784
  * @public
2768
2785
  */
2769
2786
  ManagedObject.prototype.getParent = function() {
@@ -2785,7 +2802,7 @@ sap.ui.define([
2785
2802
  * @public
2786
2803
  */
2787
2804
  ManagedObject.prototype.destroy = function(bSuppressInvalidate) {
2788
- var sName;
2805
+ var sName, oBindingInfo;
2789
2806
  // ignore repeated calls
2790
2807
  if (this.bIsDestroyed) {
2791
2808
  return;
@@ -2803,15 +2820,21 @@ sap.ui.define([
2803
2820
 
2804
2821
  // Data Binding
2805
2822
  for (sName in this.mBindingInfos) {
2806
- if (this.mBindingInfos[sName].factory) {
2807
- this._detachAggregationBindingHandlers(sName);
2808
- } else {
2809
- this._detachPropertyBindingHandlers(sName);
2823
+ oBindingInfo = this.mBindingInfos[sName];
2824
+ if (oBindingInfo.binding) {
2825
+ if (oBindingInfo.factory) {
2826
+ this._detachAggregationBindingHandlers(sName);
2827
+ } else {
2828
+ this._detachPropertyBindingHandlers(sName);
2829
+ }
2810
2830
  }
2811
2831
  }
2812
2832
 
2813
2833
  for (sName in this.mObjectBindingInfos) {
2814
- this._detachObjectBindingHandlers(sName);
2834
+ oBindingInfo = this.mObjectBindingInfos[sName];
2835
+ if (oBindingInfo.binding) {
2836
+ this._detachObjectBindingHandlers(oBindingInfo);
2837
+ }
2815
2838
  }
2816
2839
 
2817
2840
  if (this.exit) {
@@ -2877,13 +2900,6 @@ sap.ui.define([
2877
2900
  this.bIsDestroyed = true;
2878
2901
  };
2879
2902
 
2880
-
2881
- // DataBinding
2882
- /**
2883
- * Binding parser to use.
2884
- */
2885
- ManagedObject.bindingParser = BindingParser.simpleParser;
2886
-
2887
2903
  /**
2888
2904
  * Determines whether a given object contains binding information instead of a
2889
2905
  * value or aggregated controls. The method is used in applySettings for processing
@@ -2933,32 +2949,15 @@ sap.ui.define([
2933
2949
  * @private
2934
2950
  */
2935
2951
  ManagedObject.prototype.extractBindingInfo = function(oValue, oScope, bDetectValue) {
2952
+ var oBindingInfo = BindingInfo.extract(oValue, oScope, bDetectValue);
2936
2953
  // property:{path:"path", template:oTemplate}
2937
- if (oValue && typeof oValue === "object") {
2938
- if (oValue.Type) {
2939
- // if value contains the 'Type' property (capital 'T'), this is not a binding info.
2940
- return undefined;
2941
- } else if (oValue[sUI5ObjectMarker]) {
2942
- // no bindingInfo, delete marker
2943
- delete oValue[sUI5ObjectMarker];
2944
- } else if (oValue.ui5object) {
2945
- // if value contains ui5object property, this is not a binding info,
2946
- // remove it and not check for path or parts property
2947
- delete oValue.ui5object;
2948
- } else if (oValue.path != undefined || oValue.parts || (bDetectValue && oValue.value != undefined)) {
2949
- // allow JSON syntax for templates
2950
- if (oValue.template) {
2951
- oValue.template = ManagedObject.create(oValue.template);
2952
- }
2953
- return oValue;
2954
- }
2955
- }
2956
-
2957
- // property:"{path}" or "\{path\}"
2958
- if (typeof oValue === "string") {
2959
- // either returns a binding info or an unescaped string or undefined - depending on binding syntax
2960
- return ManagedObject.bindingParser(oValue, oScope, true);
2954
+ // Binding templates should only be constructed from object syntax,
2955
+ // string representation for templates is not supported
2956
+ if (typeof oValue === "object" && oBindingInfo && oBindingInfo.template) {
2957
+ // allow JSON syntax for templates
2958
+ oBindingInfo.template = ManagedObject.create(oBindingInfo.template);
2961
2959
  }
2960
+ return oBindingInfo;
2962
2961
  };
2963
2962
 
2964
2963
  /**
@@ -2984,6 +2983,23 @@ sap.ui.define([
2984
2983
  return this.mBindingInfos[sName];
2985
2984
  };
2986
2985
 
2986
+ /**
2987
+ * Returns the object binding info for the given model.
2988
+ *
2989
+ * The binding info contains information about path, binding object, format options, sorter, filter etc.
2990
+ * for the model. As the binding object is only created when the model becomes available,
2991
+ * the <code>binding</code> property may be undefined.
2992
+ *
2993
+ * @param {string} [sModelName=undefined] Non-empty name of the model or <code>undefined</code>
2994
+ * Omitting the model name (or using the value <code>undefined</code>) is explicitly allowed and
2995
+ * refers to the default model.
2996
+ * @returns {object} A binding info object, containing at least a <code>path</code> and additional properties
2997
+ * @private
2998
+ */
2999
+ ManagedObject.prototype._getObjectBindingInfo = function(sModelName) {
3000
+ return this.mObjectBindingInfos[sModelName];
3001
+ };
3002
+
2987
3003
  /**
2988
3004
  * Configuration for the binding of a managed object
2989
3005
  *
@@ -3038,8 +3054,7 @@ sap.ui.define([
3038
3054
  */
3039
3055
  ManagedObject.prototype.bindObject = function(oBindingInfo) {
3040
3056
  var sModelName,
3041
- sPath,
3042
- iSeparatorPos;
3057
+ sPath;
3043
3058
 
3044
3059
  // support legacy notation (sPath, mParameters)
3045
3060
  if (typeof oBindingInfo == "string") {
@@ -3048,21 +3063,13 @@ sap.ui.define([
3048
3063
  path: sPath,
3049
3064
  parameters: arguments[1]
3050
3065
  };
3051
- } else {
3052
- sPath = oBindingInfo.path;
3053
- }
3054
-
3055
- // if a model separator is found in the path, extract model name and path
3056
- iSeparatorPos = sPath.indexOf(">");
3057
- if (iSeparatorPos > 0) {
3058
- oBindingInfo.model = sPath.substr(0, iSeparatorPos);
3059
- oBindingInfo.path = sPath.substr(iSeparatorPos + 1);
3060
3066
  }
3061
3067
 
3068
+ oBindingInfo = BindingInfo.createObject(oBindingInfo);
3062
3069
  sModelName = oBindingInfo.model;
3063
3070
 
3064
3071
  // if old binding exists, clean it up
3065
- if ( this.mObjectBindingInfos[sModelName] ) {
3072
+ if ( this.getObjectBinding(sModelName) ) {
3066
3073
  this.unbindObject(sModelName, /* _bSkipUpdateBindingContext */ true);
3067
3074
  // We don't push down context changes here
3068
3075
  // Either this will happen with the _bindObject call below or the model
@@ -3079,75 +3086,25 @@ sap.ui.define([
3079
3086
  return this;
3080
3087
  };
3081
3088
 
3089
+ function logError(sFunctionName) {
3090
+ Log.error("Unexpected call of '" + sFunctionName + "'.");
3091
+ }
3092
+
3082
3093
  /**
3083
3094
  * Create object binding.
3084
3095
  *
3085
3096
  * @param {sap.ui.base.ManagedObject.ObjectBindingInfo} oBindingInfo The bindingInfo object
3086
3097
  * @private
3087
3098
  */
3088
- ManagedObject.prototype._bindObject = function(oBindingInfo) {
3089
- var oBinding,
3090
- oContext,
3091
- sModelName,
3092
- oModel,
3093
- that = this;
3094
-
3095
- var fnChangeHandler = function(oEvent) {
3096
- that.setElementBindingContext(oBinding.getBoundContext(), sModelName);
3097
- };
3098
-
3099
- var fnDataStateChangeHandler = function(oEvent) {
3100
- var oDataState = oBinding.getDataState();
3101
- if (!oDataState) {
3102
- return;
3103
- }
3104
- //inform generic refreshDataState method
3105
- if (that.refreshDataState) {
3106
- that.refreshDataState('', oDataState);
3107
- }
3108
- };
3109
-
3110
- sModelName = oBindingInfo.model;
3111
- oModel = this.getModel(sModelName);
3112
-
3113
- oContext = this.getBindingContext(sModelName);
3114
-
3115
- oBinding = oModel.bindContext(oBindingInfo.path, oContext, oBindingInfo.parameters);
3116
- if (oBindingInfo.suspended) {
3117
- oBinding.suspend(true);
3118
- }
3119
- oBinding.attachChange(fnChangeHandler);
3120
- oBindingInfo.binding = oBinding;
3121
- oBindingInfo.modelChangeHandler = fnChangeHandler;
3122
- oBindingInfo.dataStateChangeHandler = fnDataStateChangeHandler;
3123
-
3124
- oBinding.attachEvents(oBindingInfo.events);
3125
-
3126
- if (this.refreshDataState) {
3127
- oBinding.attachAggregatedDataStateChange(fnDataStateChangeHandler);
3128
- }
3129
-
3130
- oBinding.initialize();
3131
- };
3099
+ ManagedObject.prototype._bindObject = logError.bind(null, "_bindObject");
3132
3100
 
3133
3101
  /**
3134
3102
  * Detach all object binding event handler
3135
3103
  *
3136
- * @param {string} sModelName Name of the model to detach the handler for.
3104
+ * @param {sap.ui.base.ManagedObject.ObjectBindingInfo} oBindingInfo The BindingInfo to detach the handler for.
3137
3105
  * @private
3138
3106
  */
3139
- ManagedObject.prototype._detachObjectBindingHandlers = function(sModelName) {
3140
- var oBindingInfo = this.mObjectBindingInfos[sModelName];
3141
- if (oBindingInfo) {
3142
- if (oBindingInfo.binding) {
3143
- oBindingInfo.binding.detachChange(oBindingInfo.modelChangeHandler);
3144
- oBindingInfo.binding.detachEvents(oBindingInfo.events);
3145
- if (this.refreshDataState) {
3146
- oBindingInfo.binding.detachAggregatedDataStateChange(oBindingInfo.dataStateChangeHandler);
3147
- }
3148
- }
3149
- }
3150
- };
3107
+ ManagedObject.prototype._detachObjectBindingHandlers = logError.bind(null, "_detachObjectBindingHandlers");
3151
3108
 
3152
3109
  /**
3153
3110
  * Removes the defined binding context of this object, all bindings will now resolve
@@ -3160,23 +3117,16 @@ sap.ui.define([
3160
3117
  ManagedObject.prototype.unbindObject = function(sModelName, /* internal use only */ _bSkipUpdateBindingContext) {
3161
3118
  var oBindingInfo = this.mObjectBindingInfos[sModelName];
3162
3119
  if (oBindingInfo) {
3163
- if (oBindingInfo.binding) {
3164
- if (!this._bIsBeingDestroyed) {
3165
- this._detachObjectBindingHandlers(sModelName);
3166
- }
3167
- oBindingInfo.binding.destroy();
3168
- }
3169
3120
  delete this.mObjectBindingInfos[sModelName];
3170
- delete this.mElementBindingContexts[sModelName];
3171
- if ( !_bSkipUpdateBindingContext ) {
3172
- this.updateBindingContext(false, sModelName);
3173
- this.propagateProperties(sModelName);
3174
- this.fireModelContextChange();
3121
+ if (oBindingInfo.binding) {
3122
+ this._unbindObject(oBindingInfo, sModelName, /* internal use only */ _bSkipUpdateBindingContext);
3175
3123
  }
3176
3124
  }
3177
3125
  return this;
3178
3126
  };
3179
3127
 
3128
+ ManagedObject.prototype._unbindObject = logError.bind(null, "_unbindObject");
3129
+
3180
3130
  /**
3181
3131
  * Bind the object to the referenced entity in the model, which is used as the binding context
3182
3132
  * to resolve bound properties or aggregations of the object itself and all of its children
@@ -3264,11 +3214,16 @@ sap.ui.define([
3264
3214
  * subclass of <code>sap.ui.model.PropertyBinding</code>
3265
3215
  * @property {object} [events=null]
3266
3216
  * Map of event handler functions keyed by the name of the binding events that they should be attached to
3267
- * @property {sap.ui.base.ManagedObject.PropertyBindingInfo[]} [parts]
3217
+ * @property {Array<string|sap.ui.base.ManagedObject.PropertyBindingInfo>} [parts]
3268
3218
  * Array of binding info objects for the parts of a composite binding; the structure of
3269
3219
  * each binding info is the same as described for the <code>oBindingInfo</code> as a whole.
3270
3220
  *
3271
- * <b>Note</b>: recursive composite bindings are currently not supported
3221
+ * If a part is not specified as a binding info object but as a simple string, a binding info object
3222
+ * will be created with that string as <code>path</code>. The string may start with a model name prefix
3223
+ * (see property <code>path</code>).
3224
+ *
3225
+ * <b>Note</b>: recursive composite bindings are currently not supported. Therefore, a part must not
3226
+ * contain a <code>parts</code> property.
3272
3227
  *
3273
3228
  * @public
3274
3229
  */
@@ -3345,8 +3300,7 @@ sap.ui.define([
3345
3300
  * @public
3346
3301
  */
3347
3302
  ManagedObject.prototype.bindProperty = function(sName, oBindingInfo, /* undocumented, old API only: */ _vFormat, _sMode) {
3348
- var iSeparatorPos,
3349
- bAvailable = true,
3303
+ var bAvailable = true,
3350
3304
  oProperty = this.getMetadata().getPropertyLikeSetting(sName);
3351
3305
 
3352
3306
  // check whether property or alternative type on aggregation exists
@@ -3359,71 +3313,20 @@ sap.ui.define([
3359
3313
  oBindingInfo = {
3360
3314
  parts: [ {
3361
3315
  path: oBindingInfo,
3362
- type: _vFormat instanceof Type ? _vFormat : undefined,
3316
+ type: BaseObject.isA(_vFormat, "sap.ui.model.Type") ? _vFormat : undefined,
3363
3317
  mode: _sMode
3364
3318
  } ],
3365
3319
  formatter: typeof _vFormat === 'function' ? _vFormat : undefined
3366
3320
  };
3367
3321
  }
3368
3322
 
3369
- // only one binding object with one binding specified
3370
- if (!oBindingInfo.parts) {
3371
- oBindingInfo.parts = [];
3372
- oBindingInfo.parts[0] = {
3373
- path: oBindingInfo.path,
3374
- targetType: oBindingInfo.targetType,
3375
- type: oBindingInfo.type,
3376
- suspended: oBindingInfo.suspended,
3377
- formatOptions: oBindingInfo.formatOptions,
3378
- constraints: oBindingInfo.constraints,
3379
- model: oBindingInfo.model,
3380
- mode: oBindingInfo.mode,
3381
- value: oBindingInfo.value
3382
- };
3383
- delete oBindingInfo.path;
3384
- delete oBindingInfo.targetType;
3385
- delete oBindingInfo.mode;
3386
- delete oBindingInfo.model;
3387
- delete oBindingInfo.value;
3388
- }
3389
-
3390
- for ( var i = 0; i < oBindingInfo.parts.length; i++ ) {
3391
-
3392
- // Plain strings as parts are taken as paths of bindings
3393
- var oPart = oBindingInfo.parts[i];
3394
- if (typeof oPart == "string") {
3395
- oPart = { path: oPart };
3396
- oBindingInfo.parts[i] = oPart;
3397
- }
3398
-
3399
- // if a model separator is found in the path, extract model name and path
3400
- if (oPart.path !== undefined) {
3401
- iSeparatorPos = oPart.path.indexOf(">");
3402
- if (iSeparatorPos > 0) {
3403
- oPart.model = oPart.path.substr(0, iSeparatorPos);
3404
- oPart.path = oPart.path.substr(iSeparatorPos + 1);
3405
- }
3406
- }
3407
- // if a formatter exists the binding mode can be one way or one time only
3408
- if (oBindingInfo.formatter && oPart.mode != BindingMode.OneWay && oPart.mode != BindingMode.OneTime) {
3409
- oPart.mode = BindingMode.OneWay;
3410
- }
3411
-
3412
- // Check for model availability for model bindings
3413
- if (oPart.value === undefined && !this.getModel(oPart.model)) {
3414
- bAvailable = false;
3415
- }
3416
- }
3417
-
3418
- //Initialize skip properties
3419
- oBindingInfo.skipPropertyUpdate = 0;
3420
- oBindingInfo.skipModelUpdate = 0;
3421
-
3422
3323
  // if property is already bound, unbind it first
3423
3324
  if (this.isBound(sName)) {
3424
3325
  this.unbindProperty(sName, true);
3425
3326
  }
3426
3327
 
3328
+ oBindingInfo = BindingInfo.createProperty(oBindingInfo);
3329
+
3427
3330
  // store binding info to create the binding, as soon as the model is available, or when the model is changed
3428
3331
  this.mBindingInfos[sName] = oBindingInfo;
3429
3332
 
@@ -3431,6 +3334,14 @@ sap.ui.define([
3431
3334
  this._observer.bindingChange(this, sName, "prepare", oBindingInfo, "property");
3432
3335
  }
3433
3336
 
3337
+ // Check if all models are available before creating bindings
3338
+ for ( var i = 0; i < oBindingInfo.parts.length; i++ ) {
3339
+ if (oBindingInfo.parts[i].value === undefined && !this.getModel(oBindingInfo.parts[i].model)) {
3340
+ bAvailable = false;
3341
+ break;
3342
+ }
3343
+ }
3344
+
3434
3345
  // if the models are already available, create the binding
3435
3346
  if (bAvailable) {
3436
3347
  this._bindProperty(sName, oBindingInfo);
@@ -3439,127 +3350,35 @@ sap.ui.define([
3439
3350
  };
3440
3351
 
3441
3352
  ManagedObject.prototype._bindProperty = function(sName, oBindingInfo) {
3442
- var oModel,
3443
- oContext,
3444
- oBinding,
3445
- sMode,
3446
- sCompositeMode = BindingMode.TwoWay,
3447
- oType,
3448
- clType,
3449
- oPropertyInfo = this.getMetadata().getPropertyLikeSetting(sName), // TODO fix handling of hidden entities?
3450
- sInternalType = oPropertyInfo._iKind === /* PROPERTY */ 0 ? oPropertyInfo.type : oPropertyInfo.altTypes[0],
3451
- that = this,
3452
- aBindings = [],
3453
- fnModelChangeHandler = function(oEvent){
3454
- that.updateProperty(sName);
3455
- //clear Messages from messageManager
3456
- var oDataState = oBinding.getDataState();
3457
- if (oDataState) {
3458
- var oControlMessages = oDataState.getControlMessages();
3459
- if (oControlMessages && oControlMessages.length > 0) {
3460
- var oMessageManager = sap.ui.getCore().getMessageManager();
3461
- oDataState.setControlMessages([]); //remove the controlMessages before informing manager to avoid 'dataStateChange' event to fire
3462
- if (oControlMessages) {
3463
- oMessageManager.removeMessages(oControlMessages);
3464
- }
3465
- }
3466
- oDataState.setInvalidValue(undefined); //assume that the model always sends valid data
3467
- }
3468
- if (oBinding.getBindingMode() === BindingMode.OneTime && oBinding.isResolved()) {
3469
- // if binding is one time but not resolved yet we don't destroy it yet.
3470
- oBinding.detachChange(fnModelChangeHandler);
3471
- if (this.refreshDataState) {
3472
- oBinding.detachAggregatedDataStateChange(fnDataStateChangeHandler);
3473
- }
3474
- oBinding.detachEvents(oBindingInfo.events);
3475
- }
3476
- },
3477
- fnDataStateChangeHandler = function(){
3478
- var oDataState = oBinding.getDataState();
3479
- if (!oDataState) {
3480
- return;
3481
- }
3482
- //inform generic refreshDataState method
3483
- if (that.refreshDataState) {
3484
- that.refreshDataState(sName, oDataState);
3485
- }
3486
- };
3487
-
3488
- oBindingInfo.parts.forEach(function(oPart) {
3489
- // get context and model for this part
3490
- oContext = that.getBindingContext(oPart.model);
3491
- oModel = that.getModel(oPart.model);
3492
-
3493
- // Create type instance if needed
3494
- oType = oPart.type;
3495
- if (typeof oType == "string") {
3496
- clType = ObjectPath.get(oType);
3497
- if (typeof clType !== "function") {
3498
- throw new Error("Cannot find type \"" + oType + "\" used in control \"" + that.getId() + "\"!");
3499
- }
3500
- oType = new clType(oPart.formatOptions, oPart.constraints);
3501
- }
3502
-
3503
- if (oPart.value !== undefined) {
3504
- oBinding = new StaticBinding(oPart.value);
3505
- } else {
3506
- oBinding = oModel.bindProperty(oPart.path, oContext, oPart.parameters || oBindingInfo.parameters);
3507
- }
3508
- oBinding.setType(oType, oPart.targetType || sInternalType);
3509
- oBinding.setFormatter(oPart.formatter);
3510
- if (oPart.suspended) {
3511
- oBinding.suspend(true);
3353
+ /* Special case for handling StaticBindings:
3354
+ If all parts are a StaticBinding no mixin of the binding relevant code
3355
+ is done via a Model. In this case we need to handle these static
3356
+ bindings manually by simulating its static behavior:
3357
+ - call formatter
3358
+ - call property mutator
3359
+ If at least one part refers to a real Model this
3360
+ code will be overwritten by the mixin and works as before.*/
3361
+ var bIsStaticOnly = true;
3362
+ for (var i = 0; i < oBindingInfo.parts.length; i++) {
3363
+ if (oBindingInfo.parts[i].value === undefined) {
3364
+ bIsStaticOnly = false;
3365
+ break;
3512
3366
  }
3513
-
3514
- sMode = oPart.mode || (oModel && oModel.getDefaultBindingMode()) || BindingMode.TwoWay;
3515
- oBinding.setBindingMode(sMode);
3516
-
3517
- // Only if all parts have twoway binding enabled, the composite binding will also have twoway binding
3518
- if (sMode !== BindingMode.TwoWay) {
3519
- sCompositeMode = BindingMode.OneWay;
3520
- }
3521
-
3522
- aBindings.push(oBinding);
3523
- });
3524
-
3525
- // check if we have a composite binding or a formatter function created by the BindingParser which has property textFragments
3526
- if (aBindings.length > 1 || ( oBindingInfo.formatter && oBindingInfo.formatter.textFragments )) {
3527
- // Create type instance if needed
3528
- oType = oBindingInfo.type;
3529
- if (typeof oType == "string") {
3530
- clType = ObjectPath.get(oType);
3531
- oType = new clType(oBindingInfo.formatOptions, oBindingInfo.constraints);
3532
- }
3533
- oBinding = new CompositeBinding(aBindings, oBindingInfo.useRawValues, oBindingInfo.useInternalValues);
3534
- oBinding.setType(oType, oBindingInfo.targetType || sInternalType);
3535
- oBinding.setBindingMode(oBindingInfo.mode || sCompositeMode);
3536
- } else {
3537
- oBinding = aBindings[0];
3538
- }
3539
-
3540
- oBinding.attachChange(fnModelChangeHandler);
3541
- if (this.refreshDataState) {
3542
- oBinding.attachAggregatedDataStateChange(fnDataStateChangeHandler);
3543
3367
  }
3544
-
3545
- // set only one formatter function if any
3546
- // because the formatter gets the context of the element, we have to set the context via proxy to ensure compatibility
3547
- // for formatter function which is now called by the property binding
3548
- // proxy formatter here because "this" is the correct cloned object
3549
- if (typeof oBindingInfo.formatter === "function") {
3550
- oBinding.setFormatter(oBindingInfo.formatter.bind(this));
3551
- }
3552
-
3553
- // Set additional information on the binding info
3554
- oBindingInfo.binding = oBinding;
3555
- oBindingInfo.modelChangeHandler = fnModelChangeHandler;
3556
- oBindingInfo.dataStateChangeHandler = fnDataStateChangeHandler;
3557
- oBinding.attachEvents(oBindingInfo.events);
3558
-
3559
- oBinding.initialize();
3560
-
3561
- if (this._observer) {
3562
- this._observer.bindingChange(this, sName, "ready", oBindingInfo, "property");
3368
+ // The special treatment of early 'static-only' StaticBindings is making compromises on a couple of things:
3369
+ // - no async type can be supported
3370
+ // - no handling of parse/validate exceptions
3371
+ // - observers won't be called
3372
+ if (bIsStaticOnly) {
3373
+ var aValues = [];
3374
+ oBindingInfo.parts.forEach(function(oPart) {
3375
+ aValues.push(oPart.formatter ? oPart.formatter(oPart.value) : oPart.value);
3376
+ });
3377
+ var vValue = oBindingInfo.formatter ? oBindingInfo.formatter(aValues) : aValues.join(" ");
3378
+ var oPropertyInfo = this.getMetadata().getPropertyLikeSetting(sName);
3379
+ this[oPropertyInfo._sMutator](vValue);
3380
+ } else {
3381
+ logError.call(this, "_bindProperty");
3563
3382
  }
3564
3383
  };
3565
3384
 
@@ -3573,22 +3392,7 @@ sap.ui.define([
3573
3392
  * @param {string} sName the name of the property
3574
3393
  * @private
3575
3394
  */
3576
- ManagedObject.prototype._detachPropertyBindingHandlers = function(sName) {
3577
- var oBindingInfo = this.mBindingInfos[sName],
3578
- oBinding;
3579
- if (oBindingInfo) {
3580
- oBinding = oBindingInfo.binding;
3581
- if (oBinding) {
3582
- oBinding.detachChange(oBindingInfo.modelChangeHandler);
3583
- oBinding.detachEvents(oBindingInfo.events);
3584
- /* to reset messages on a control we need to detach the datastate handler after destroy,
3585
- as binding destroy clears up validation messages */
3586
- if (this.refreshDataState && this._bIsBeingDestroyed) {
3587
- oBinding.detachAggregatedDataStateChange(oBindingInfo.dataStateChangeHandler);
3588
- }
3589
- }
3590
- }
3591
- };
3395
+ ManagedObject.prototype._detachPropertyBindingHandlers = function(sName) { };
3592
3396
 
3593
3397
  /**
3594
3398
  * Unbind the property from the model
@@ -3598,21 +3402,11 @@ sap.ui.define([
3598
3402
  * @returns {this} reference to the instance itself
3599
3403
  * @public
3600
3404
  */
3601
- ManagedObject.prototype.unbindProperty = function(sName, bSuppressReset){
3602
- var oBindingInfo = this.mBindingInfos[sName],
3603
- oBinding;
3405
+ ManagedObject.prototype.unbindProperty = function(sName, bSuppressReset) {
3406
+ var oBindingInfo = this.mBindingInfos[sName];
3604
3407
  if (oBindingInfo) {
3605
- oBinding = oBindingInfo.binding;
3606
- if (oBinding) {
3607
- if (!this._bIsBeingDestroyed) {
3608
- this._detachPropertyBindingHandlers(sName);
3609
- }
3610
- oBinding.destroy();
3611
- /* to reset messages on a control we need to detach the datastate handler after destroy,
3612
- as binding destroy clears up validation messages */
3613
- if (this.refreshDataState && !this._bIsBeingDestroyed) {
3614
- oBinding.detachAggregatedDataStateChange(oBindingInfo.dataStateChangeHandler);
3615
- }
3408
+ if (oBindingInfo.binding) {
3409
+ this._unbindProperty(oBindingInfo, sName);
3616
3410
  }
3617
3411
 
3618
3412
  if (this._observer && !this._bIsBeingDestroyed) {
@@ -3627,6 +3421,8 @@ sap.ui.define([
3627
3421
  return this;
3628
3422
  };
3629
3423
 
3424
+ ManagedObject.prototype._unbindProperty = logError.bind(null, "_unbindProperty");
3425
+
3630
3426
  /**
3631
3427
  * Generic method which is called, whenever a property binding is changed.
3632
3428
  *
@@ -3637,50 +3433,7 @@ sap.ui.define([
3637
3433
  * Name of the property to update
3638
3434
  * @private
3639
3435
  */
3640
- ManagedObject.prototype.updateProperty = function(sName) {
3641
- var oBindingInfo = this.mBindingInfos[sName],
3642
- oBinding = oBindingInfo.binding,
3643
- oPropertyInfo = this.getMetadata().getPropertyLikeSetting(sName),
3644
- that = this;
3645
-
3646
- function handleException(oException) {
3647
- if (oException instanceof FormatException) {
3648
- that.fireFormatError({
3649
- element : that,
3650
- property : sName,
3651
- type : oBinding.getType(),
3652
- newValue : oBinding.getValue(),
3653
- oldValue : that[oPropertyInfo._sGetter](),
3654
- exception: oException,
3655
- message: oException.message
3656
- }, false, true); // bAllowPreventDefault, bEnableEventBubbling
3657
- Log.error("FormatException in property '" + sName + "' of '" + that + "': " + oException.message +
3658
- "\nHint: single properties referenced in composite bindings and within binding expressions are automatically converted " +
3659
- "into the type of the bound control property, unless a different 'targetType' is specified. targetType:'any' may avoid " +
3660
- "the conversion and lead to the expected behavior.");
3661
- oBindingInfo.skipModelUpdate++;
3662
- that.resetProperty(sName);
3663
- oBindingInfo.skipModelUpdate--;
3664
- } else {
3665
- throw oException;
3666
- }
3667
- }
3668
-
3669
- // If model change was triggered by the property itself, don't call the setter again
3670
- if (oBindingInfo.skipPropertyUpdate) {
3671
- return;
3672
- }
3673
-
3674
- SyncPromise.resolve().then(function() {
3675
- return oBinding.getExternalValue();
3676
- }).then(function(oValue) {
3677
- oBindingInfo.skipModelUpdate++;
3678
- that[oPropertyInfo._sMutator](oValue);
3679
- oBindingInfo.skipModelUpdate--;
3680
- }).catch(function(oException) {
3681
- handleException(oException);
3682
- }).unwrap();
3683
- };
3436
+ ManagedObject.prototype.updateProperty = function(sName) { };
3684
3437
 
3685
3438
  /**
3686
3439
  * Update the property in the model if two way data binding mode is enabled
@@ -3690,72 +3443,7 @@ sap.ui.define([
3690
3443
  * @param {any} oOldValue the previous value of the property
3691
3444
  * @private
3692
3445
  */
3693
- ManagedObject.prototype.updateModelProperty = function(sName, oValue, oOldValue){
3694
- var oBindingInfo, oBinding,
3695
- that = this;
3696
-
3697
- function handleException(oException) {
3698
- var mErrorParameters = {
3699
- element: that,
3700
- property: sName,
3701
- type: oBinding.getType(),
3702
- newValue: oValue,
3703
- oldValue: oOldValue,
3704
- exception: oException,
3705
- message: oException.message
3706
- };
3707
- if (oException instanceof ParseException) {
3708
- that.fireParseError(mErrorParameters, false, true); // mParameters, bAllowPreventDefault, bEnableEventBubbling
3709
- } else if (oException instanceof ValidateException) {
3710
- that.fireValidationError(mErrorParameters, false, true); // mParameters, bAllowPreventDefault, bEnableEventBubbling
3711
- } else {
3712
- throw oException;
3713
- }
3714
- }
3715
-
3716
- function handleSuccess() {
3717
- var mSuccessParameters = {
3718
- element: that,
3719
- property: sName,
3720
- type: oBinding.getType(),
3721
- newValue: oValue,
3722
- oldValue: oOldValue
3723
- };
3724
- // Only fire validation success, if a type is used
3725
- if (oBinding.hasValidation()) {
3726
- that.fireValidationSuccess(mSuccessParameters, false, true); // bAllowPreventDefault, bEnableEventBubbling
3727
- }
3728
- }
3729
-
3730
- if (this.isBound(sName)) {
3731
- var oBindingInfo = this.mBindingInfos[sName],
3732
- oBinding = oBindingInfo.binding;
3733
-
3734
- // If property change was triggered by the model, don't update the model again
3735
- if (oBindingInfo.skipModelUpdate || (oBinding && oBinding.isSuspended())) {
3736
- return;
3737
- }
3738
-
3739
- // only two-way bindings allow model updates
3740
- if (oBinding && oBinding.getBindingMode() == BindingMode.TwoWay) {
3741
- oBindingInfo.skipPropertyUpdate++;
3742
- SyncPromise.resolve(oValue).then(function(oValue) {
3743
- return oBinding.setExternalValue(oValue);
3744
- }).then(function() {
3745
- oBindingInfo.skipPropertyUpdate--;
3746
- return oBinding.getExternalValue();
3747
- }).then(function(oExternalValue) {
3748
- if (oValue != oExternalValue) {
3749
- that.updateProperty(sName);
3750
- }
3751
- handleSuccess();
3752
- }).catch(function(oException) {
3753
- oBindingInfo.skipPropertyUpdate--;
3754
- handleException(oException);
3755
- }).unwrap();
3756
- }
3757
- }
3758
- };
3446
+ ManagedObject.prototype.updateModelProperty = function(sName, oValue, oOldValue) { };
3759
3447
 
3760
3448
  // a non-falsy value used as default for 'templateShareable'.
3761
3449
  var MAYBE_SHAREABLE_OR_NOT = 1;
@@ -3884,26 +3572,11 @@ sap.ui.define([
3884
3572
  return this;
3885
3573
  }
3886
3574
 
3887
-
3888
3575
  // if aggregation is already bound, unbind it first
3889
3576
  if (this.isBound(sName)) {
3890
3577
  this.unbindAggregation(sName);
3891
3578
  }
3892
3579
 
3893
- // check whether a template has been provided, which is required for proper processing of the binding
3894
- // If aggregation is marked correspondingly in the metadata, factory can be omitted (usually requires an updateXYZ method)
3895
- if (!(oBindingInfo.template || oBindingInfo.factory)) {
3896
- if ( oAggregationInfo._doesNotRequireFactory ) {
3897
- // add a dummy factory as property 'factory' is used to distinguish between property- and list-binding
3898
- oBindingInfo.factory = function() {
3899
- throw new Error("dummy factory called unexpectedly ");
3900
- };
3901
- } else {
3902
- throw new Error("Missing template or factory function for aggregation " + sName + " of " + this + " !");
3903
- }
3904
- }
3905
-
3906
- // if we have a template we will create a factory function
3907
3580
  if (oBindingInfo.template) {
3908
3581
  // set default for templateShareable
3909
3582
  if ( oBindingInfo.template._sapui_candidateForDestroy ) {
@@ -3918,21 +3591,16 @@ sap.ui.define([
3918
3591
  if (oBindingInfo.templateShareable === undefined) {
3919
3592
  oBindingInfo.templateShareable = MAYBE_SHAREABLE_OR_NOT;
3920
3593
  }
3921
- oBindingInfo.factory = function(sId) {
3922
- return oBindingInfo.template.clone(sId);
3923
- };
3924
- }
3925
-
3926
- // if a model separator is found in the path, extract model name and path
3927
- var iSeparatorPos = oBindingInfo.path.indexOf(">");
3928
- if (iSeparatorPos > 0) {
3929
- oBindingInfo.model = oBindingInfo.path.substr(0, iSeparatorPos);
3930
- oBindingInfo.path = oBindingInfo.path.substr(iSeparatorPos + 1);
3931
3594
  }
3595
+ oBindingInfo = BindingInfo.createAggregation(oBindingInfo, oAggregationInfo._doesNotRequireFactory);
3932
3596
 
3933
3597
  // store binding info to create the binding, as soon as the model is available, or when the model is changed
3934
3598
  this.mBindingInfos[sName] = oBindingInfo;
3935
3599
 
3600
+ if (!(oBindingInfo.template || oBindingInfo.factory)) {
3601
+ throw new Error("Missing template or factory function for aggregation " + sName + " of " + this + " !");
3602
+ }
3603
+
3936
3604
  if (this._observer) {
3937
3605
  this._observer.bindingChange(this, sName, "prepare", oBindingInfo, "aggregation");
3938
3606
  }
@@ -3951,71 +3619,7 @@ sap.ui.define([
3951
3619
  * @param {object} oBindingInfo The bindingInfo object
3952
3620
  * @private
3953
3621
  */
3954
- ManagedObject.prototype._bindAggregation = function(sName, oBindingInfo) {
3955
- var that = this,
3956
- oBinding,
3957
- oAggregationInfo = this.getMetadata().getAggregation(sName),
3958
- fnModelChangeHandler = function(oEvent){
3959
- var sOldOwnerId = ManagedObject._sOwnerId;
3960
- try {
3961
- ManagedObject._sOwnerId = that._sOwnerId;
3962
- oAggregationInfo.update(that, oEvent.getParameter("reason"), {
3963
- detailedReason: oEvent.getParameter("detailedReason")
3964
- });
3965
- } finally {
3966
- ManagedObject._sOwnerId = sOldOwnerId;
3967
- }
3968
- },
3969
- fnModelRefreshHandler = function(oEvent){
3970
- oAggregationInfo.refresh(that, oEvent.getParameter("reason"));
3971
- },
3972
- fnDataStateChangeHandler = function(oEvent) {
3973
- var oDataState = oBinding.getDataState();
3974
- if (!oDataState) {
3975
- return;
3976
- }
3977
- //inform generic refreshDataState method
3978
- if (that.refreshDataState) {
3979
- that.refreshDataState(sName, oDataState);
3980
- }
3981
- };
3982
-
3983
- var oModel = this.getModel(oBindingInfo.model);
3984
- if (this.isTreeBinding(sName)) {
3985
- oBinding = oModel.bindTree(oBindingInfo.path, this.getBindingContext(oBindingInfo.model), oBindingInfo.filters, oBindingInfo.parameters, oBindingInfo.sorter);
3986
- } else {
3987
- oBinding = oModel.bindList(oBindingInfo.path, this.getBindingContext(oBindingInfo.model), oBindingInfo.sorter, oBindingInfo.filters, oBindingInfo.parameters);
3988
- if (this.bUseExtendedChangeDetection) {
3989
- assert(!this.oExtendedChangeDetectionConfig || !this.oExtendedChangeDetectionConfig.symbol, "symbol function must not be set by controls");
3990
- oBinding.enableExtendedChangeDetection(!oBindingInfo.template, oBindingInfo.key, this.oExtendedChangeDetectionConfig);
3991
- }
3992
- }
3993
-
3994
- if (oBindingInfo.suspended) {
3995
- oBinding.suspend(true);
3996
- }
3997
-
3998
- oBindingInfo.binding = oBinding;
3999
- oBindingInfo.modelChangeHandler = fnModelChangeHandler;
4000
- oBindingInfo.modelRefreshHandler = fnModelRefreshHandler;
4001
- oBindingInfo.dataStateChangeHandler = fnDataStateChangeHandler;
4002
-
4003
- oBinding.attachChange(fnModelChangeHandler);
4004
-
4005
- oBinding.attachRefresh(fnModelRefreshHandler);
4006
-
4007
- oBinding.attachEvents(oBindingInfo.events);
4008
-
4009
- if (this.refreshDataState) {
4010
- oBinding.attachAggregatedDataStateChange(fnDataStateChangeHandler);
4011
- }
4012
-
4013
- oBinding.initialize();
4014
-
4015
- if (this._observer) {
4016
- this._observer.bindingChange(this, sName, "ready", oBindingInfo, "aggregation");
4017
- }
4018
- };
3622
+ ManagedObject.prototype._bindAggregation = logError.bind(null, "_bindAggregation");
4019
3623
 
4020
3624
  /**
4021
3625
  * Detach all aggregation binding event handler
@@ -4023,19 +3627,7 @@ sap.ui.define([
4023
3627
  * @param {string} sName the name of the aggregation
4024
3628
  * @private
4025
3629
  */
4026
- ManagedObject.prototype._detachAggregationBindingHandlers = function(sName) {
4027
- var oBindingInfo = this.mBindingInfos[sName];
4028
- if (oBindingInfo) {
4029
- if (oBindingInfo.binding) {
4030
- oBindingInfo.binding.detachChange(oBindingInfo.modelChangeHandler);
4031
- oBindingInfo.binding.detachRefresh(oBindingInfo.modelRefreshHandler);
4032
- oBindingInfo.binding.detachEvents(oBindingInfo.events);
4033
- if (this.refreshDataState) {
4034
- oBindingInfo.binding.detachAggregatedDataStateChange(oBindingInfo.dataStateChangeHandler);
4035
- }
4036
- }
4037
- }
4038
- };
3630
+ ManagedObject.prototype._detachAggregationBindingHandlers = logError.bind(null, "_detachAggregationBindingHandlers");
4039
3631
 
4040
3632
  /**
4041
3633
  * Unbind the aggregation from the model.
@@ -4048,7 +3640,7 @@ sap.ui.define([
4048
3640
  * @returns {this} Reference to this instance itself
4049
3641
  * @public
4050
3642
  */
4051
- ManagedObject.prototype.unbindAggregation = function(sName, bSuppressReset){
3643
+ ManagedObject.prototype.unbindAggregation = function(sName, bSuppressReset) {
4052
3644
  var oForwarder = this.getMetadata().getAggregationForwarder(sName);
4053
3645
  if (oForwarder && oForwarder.forwardBinding) {
4054
3646
  oForwarder.getTarget(this).unbindAggregation(oForwarder.targetAggregationName, bSuppressReset);
@@ -4059,10 +3651,7 @@ sap.ui.define([
4059
3651
  oAggregationInfo = this.getMetadata().getAggregation(sName);
4060
3652
  if (oBindingInfo) {
4061
3653
  if (oBindingInfo.binding) {
4062
- if (!this._bIsBeingDestroyed) {
4063
- this._detachAggregationBindingHandlers(sName);
4064
- }
4065
- oBindingInfo.binding.destroy();
3654
+ this._unbindAggregation(oBindingInfo, sName);
4066
3655
  }
4067
3656
  // remove template if any
4068
3657
  if (oBindingInfo.template ) {
@@ -4084,6 +3673,8 @@ sap.ui.define([
4084
3673
  return this;
4085
3674
  };
4086
3675
 
3676
+ ManagedObject.prototype._unbindAggregation = logError.bind(null, "_unbindAggregation");
3677
+
4087
3678
  /**
4088
3679
  * Generic method which is called whenever an aggregation binding has changed.
4089
3680
  *
@@ -4109,146 +3700,7 @@ sap.ui.define([
4109
3700
  * reason, and describe under what circumstances each value will be used.
4110
3701
  * @protected
4111
3702
  */
4112
- ManagedObject.prototype.updateAggregation = function(sName, sChangeReason, oEventInfo) {
4113
- var oBindingInfo = this.mBindingInfos[sName],
4114
- oBinding = oBindingInfo.binding,
4115
- fnFactory = oBindingInfo.factory,
4116
- oAggregationInfo = this.getMetadata().getAggregation(sName), // TODO fix handling of hidden aggregations
4117
- sGroup,
4118
- bGrouped,
4119
- aContexts,
4120
- sGroupFunction = oAggregationInfo._sMutator + "Group",
4121
- that = this;
4122
-
4123
- function getIdSuffix(oControl, iIndex) {
4124
- if (that.bUseExtendedChangeDetection) {
4125
- return ManagedObjectMetadata.uid('clone');
4126
- } else {
4127
- return oControl.getId() + "-" + iIndex;
4128
- }
4129
- }
4130
-
4131
- // Update a single aggregation with the array of contexts. Reuse existing children
4132
- // and just append or remove at the end, if some are missing or too many.
4133
- function update(oControl, aContexts, fnBefore, fnAfter) {
4134
- var aChildren = oControl[oAggregationInfo._sGetter]() || [],
4135
- oContext,
4136
- oClone;
4137
- if (aChildren.length > aContexts.length) {
4138
- for (var i = aContexts.length; i < aChildren.length; i++) {
4139
- oClone = aChildren[i];
4140
- oControl[oAggregationInfo._sRemoveMutator](oClone);
4141
- oClone.destroy("KeepDom");
4142
- }
4143
- }
4144
- for (var i = 0; i < aContexts.length; i++) {
4145
- oContext = aContexts[i];
4146
- oClone = aChildren[i];
4147
- if (fnBefore) {
4148
- fnBefore(oContext);
4149
- }
4150
- if (oClone) {
4151
- oClone.setBindingContext(oContext, oBindingInfo.model);
4152
- } else {
4153
- oClone = fnFactory(getIdSuffix(oControl, i), oContext);
4154
- oClone.setBindingContext(oContext, oBindingInfo.model);
4155
- oControl[oAggregationInfo._sMutator](oClone);
4156
- }
4157
- if (fnAfter) {
4158
- fnAfter(oContext, oClone);
4159
- }
4160
- }
4161
- }
4162
-
4163
- // Update a single aggregation with the array of contexts. Use the calculated diff to
4164
- // only add/remove children as the data has changed to minimize control updates and rendering
4165
- function updateDiff(oControl, aContexts) {
4166
- var aDiff = aContexts.diff,
4167
- aChildren = oControl[oAggregationInfo._sGetter]() || [],
4168
- oDiff, oClone, oContext, i;
4169
-
4170
- // If no diff exists or aggregation is empty, fall back to default update
4171
- if (!aDiff || aChildren.length === 0) {
4172
- update(oControl, aContexts);
4173
- return;
4174
- }
4175
-
4176
- // Loop through the diff and apply it
4177
- for (i = 0; i < aDiff.length; i++) {
4178
- oDiff = aDiff[i];
4179
- switch (oDiff.type) {
4180
- case "insert":
4181
- oContext = aContexts[oDiff.index];
4182
- oClone = fnFactory(getIdSuffix(oControl, oDiff.index), oContext);
4183
- oClone.setBindingContext(oContext, oBindingInfo.model);
4184
- oControl[oAggregationInfo._sInsertMutator](oClone, oDiff.index);
4185
- break;
4186
- case "delete":
4187
- oClone = oControl[oAggregationInfo._sRemoveMutator](oDiff.index);
4188
- oClone.destroy("KeepDom");
4189
- break;
4190
- default:
4191
- Log.error("Unknown diff type \"" + oDiff.type + "\"");
4192
- }
4193
- }
4194
-
4195
- // Loop through all children and set the binding context again. This is needed for
4196
- // indexed contexts, where inserting/deleting entries shifts the index of all following items
4197
- aChildren = oControl[oAggregationInfo._sGetter]() || [];
4198
- for (i = 0; i < aChildren.length; i++) {
4199
- aChildren[i].setBindingContext(aContexts[i], oBindingInfo.model);
4200
- }
4201
- }
4202
-
4203
- // Check the current context for its group. If the group key changes, call the
4204
- // group function on the control.
4205
- function updateGroup(oContext) {
4206
- var oNewGroup = oBinding.getGroup(oContext);
4207
- if (oNewGroup.key !== sGroup) {
4208
- var oGroupHeader;
4209
- //If factory is defined use it
4210
- if (oBindingInfo.groupHeaderFactory) {
4211
- oGroupHeader = oBindingInfo.groupHeaderFactory(oNewGroup);
4212
- }
4213
- that[sGroupFunction](oNewGroup, oGroupHeader);
4214
- sGroup = oNewGroup.key;
4215
- }
4216
- }
4217
-
4218
- // Update the tree recursively
4219
- function updateRecursive(oControl, oContexts) {
4220
- update(oControl, oContexts, null, function(oContext, oClone) {
4221
- updateRecursive(oClone, oBinding.getNodeContexts(oContext));
4222
- });
4223
- }
4224
-
4225
- if (BaseObject.isA(oBinding, "sap.ui.model.ListBinding")) {
4226
- aContexts = oBinding.getContexts(oBindingInfo.startIndex, oBindingInfo.length);
4227
- bGrouped = oBinding.isGrouped() && that[sGroupFunction];
4228
- if (bGrouped || oBinding.bWasGrouped) {
4229
- // If grouping is enabled, destroy aggregation and use updateGroup as fnBefore to create groups
4230
- this[oAggregationInfo._sDestructor]();
4231
- update(this, aContexts, bGrouped ? updateGroup : undefined);
4232
- } else if (this.bUseExtendedChangeDetection) {
4233
- // With extended change detection just update according to the diff
4234
- updateDiff(this, aContexts);
4235
- } else {
4236
- // If factory function is used without extended change detection, destroy aggregation
4237
- if (!oBindingInfo.template) {
4238
- this[oAggregationInfo._sDestructor]();
4239
- }
4240
- update(this, aContexts);
4241
- }
4242
- oBinding.bWasGrouped = bGrouped;
4243
- } else if (BaseObject.isA(oBinding, "sap.ui.model.TreeBinding")) {
4244
- // Destroy all children in case a factory function is used
4245
- if (!oBindingInfo.template) {
4246
- this[oAggregationInfo._sDestructor]();
4247
- }
4248
- // In fnAfter call update recursively for the child nodes of the current tree node
4249
- updateRecursive(this, oBinding.getRootContexts());
4250
- }
4251
- };
3703
+ ManagedObject.prototype.updateAggregation = function(sName, sChangeReason, oEventInfo) { };
4252
3704
 
4253
3705
  /**
4254
3706
  * Generic method which can be called, when an aggregation needs to be refreshed.
@@ -4262,11 +3714,7 @@ sap.ui.define([
4262
3714
  * @param {string} sName name of the aggregation to refresh
4263
3715
  * @protected
4264
3716
  */
4265
- ManagedObject.prototype.refreshAggregation = function(sName) {
4266
- var oBindingInfo = this.mBindingInfos[sName],
4267
- oBinding = oBindingInfo.binding;
4268
- oBinding.getContexts(oBindingInfo.startIndex, oBindingInfo.length);
4269
- };
3717
+ ManagedObject.prototype.refreshAggregation = function(sName) { };
4270
3718
 
4271
3719
  /**
4272
3720
  * Generic method which is called, whenever messages for this object exist.
@@ -4306,139 +3754,7 @@ sap.ui.define([
4306
3754
  *
4307
3755
  * @private
4308
3756
  */
4309
- ManagedObject.prototype.updateBindings = function(bUpdateAll, sModelName) {
4310
- var that = this,
4311
- sName,
4312
- bCanCreate,
4313
- oBindingInfo;
4314
-
4315
- /*
4316
- * Checks whether the binding for the given oBindingInfo became invalid because
4317
- * of the current model change (as identified by bUpdateAll and sModelName).
4318
- *
4319
- * Precondition: oBindingInfo contains a 'binding' object
4320
- *
4321
- * @param {object} oBindingInfo
4322
- * @returns {boolean} Whether the binding info became invalid
4323
- * @private
4324
- */
4325
- function becameInvalid(oBindingInfo) {
4326
- var aParts = oBindingInfo.parts,
4327
- i;
4328
-
4329
- if (aParts) {
4330
- if (aParts.length == 1) {
4331
- // simple property binding: invalid when the model has the same name (or updateall) and when the model instance differs
4332
- return (bUpdateAll || aParts[0].model == sModelName) && !oBindingInfo.binding.updateRequired(that.getModel(aParts[0].model));
4333
- } else {
4334
- // simple or composite binding: invalid when for any part the model has the same name (or updateall) and when the model instance for that part differs
4335
- for (i = 0; i < aParts.length; i++) {
4336
- if ( (bUpdateAll || aParts[i].model == sModelName) && !oBindingInfo.binding.aBindings[i].updateRequired(that.getModel(aParts[i].model)) ) {
4337
- return true;
4338
- }
4339
- }
4340
- }
4341
- } else {
4342
- // list or object binding: invalid when the model has the same name (or updateall) and when the model instance differs
4343
- return (bUpdateAll || oBindingInfo.model == sModelName) && !oBindingInfo.binding.updateRequired(that.getModel(oBindingInfo.model));
4344
- }
4345
- }
4346
-
4347
- /*
4348
- * Checks whether a binding can be created for the given oBindingInfo.
4349
- *
4350
- * @param {object} oBindingInfo
4351
- * @returns {boolean} Whether a binding can be created
4352
- * @private
4353
- */
4354
- function canCreate(oBindingInfo) {
4355
- var aParts = oBindingInfo.parts,
4356
- i;
4357
-
4358
- if (aParts) {
4359
- for (i = 0; i < aParts.length; i++) {
4360
- // check if model exists - ignore static bindings
4361
- if ( !that.getModel(aParts[i].model) && aParts[i].value === undefined) {
4362
- return false;
4363
- }
4364
- }
4365
- return true;
4366
- } else { // List or object binding
4367
- return !!that.getModel(oBindingInfo.model);
4368
- }
4369
- }
4370
-
4371
- /*
4372
- * Remove binding, detach all events and destroy binding object
4373
- */
4374
- function removeBinding(oBindingInfo) {
4375
- var oBinding = oBindingInfo.binding;
4376
- // Also tell the Control that the messages have been removed (if any)
4377
- if (that.refreshDataState) {
4378
- that.refreshDataState(sName, oBinding.getDataState());
4379
- }
4380
-
4381
- oBinding.detachChange(oBindingInfo.modelChangeHandler);
4382
- if (oBindingInfo.modelRefreshHandler) { // only list bindings currently have a refresh handler attached
4383
- oBinding.detachRefresh(oBindingInfo.modelRefreshHandler);
4384
- }
4385
- oBinding.detachEvents(oBindingInfo.events);
4386
- oBinding.destroy();
4387
- // remove all binding related data from the binding info
4388
- delete oBindingInfo.binding;
4389
- delete oBindingInfo.modelChangeHandler;
4390
- delete oBindingInfo.dataStateChangeHandler;
4391
- delete oBindingInfo.modelRefreshHandler;
4392
- }
4393
-
4394
- // create object bindings if they don't exist yet
4395
- for ( sName in this.mObjectBindingInfos ) {
4396
- oBindingInfo = this.mObjectBindingInfos[sName];
4397
- bCanCreate = canCreate(oBindingInfo);
4398
- // if there is a binding and if it became invalid through the current model change, then remove it
4399
- if ( oBindingInfo.binding && becameInvalid(oBindingInfo) ) {
4400
- removeBinding(oBindingInfo);
4401
- // if model does not exists anymore, also delete the BindingContext
4402
- if (!bCanCreate) {
4403
- delete this.mElementBindingContexts[sName];
4404
- }
4405
- }
4406
-
4407
- // if there is no binding and if all required information is available, create a binding object
4408
- if ( !oBindingInfo.binding && bCanCreate ) {
4409
- this._bindObject(oBindingInfo);
4410
- }
4411
- }
4412
-
4413
- // create property and aggregation bindings if they don't exist yet
4414
- for ( sName in this.mBindingInfos ) {
4415
-
4416
- oBindingInfo = this.mBindingInfos[sName];
4417
-
4418
- // if there is a binding and if it became invalid through the current model change, then remove it
4419
- if ( oBindingInfo.binding && becameInvalid(oBindingInfo) ) {
4420
- if (this._observer) {
4421
- var sMember = oBindingInfo.factory ? "aggregation" : "property";
4422
- this._observer.bindingChange(this, sName, "remove", oBindingInfo, sMember);
4423
- }
4424
-
4425
- removeBinding(oBindingInfo);
4426
- }
4427
-
4428
- // if there is no binding and if all required information is available, create a binding object
4429
- if ( !oBindingInfo.binding && canCreate(oBindingInfo) ) {
4430
- if (oBindingInfo.factory) {
4431
- this._bindAggregation(sName, oBindingInfo);
4432
- } else {
4433
- this._bindProperty(sName, oBindingInfo);
4434
- }
4435
- }
4436
-
4437
- }
4438
-
4439
-
4440
- };
4441
-
3757
+ ManagedObject.prototype.updateBindings = function(bUpdateAll, sModelName) { };
4442
3758
 
4443
3759
  /**
4444
3760
  * Find out whether a property or aggregation is bound
@@ -4464,18 +3780,20 @@ sap.ui.define([
4464
3780
  * refers to the default model.
4465
3781
  *
4466
3782
  * @param {string} [sModelName=undefined] Non-empty name of the model or <code>undefined</code>
4467
- * @return {sap.ui.model.ContextBinding} Context binding for the given model name or <code>undefined</code>
3783
+ * @returns {sap.ui.model.ContextBinding|undefined} Context binding for the given model name or <code>undefined</code>
4468
3784
  * @public
4469
3785
  */
4470
3786
  ManagedObject.prototype.getObjectBinding = function(sModelName){
4471
- return this.mObjectBindingInfos[sModelName] && this.mObjectBindingInfos[sModelName].binding;
3787
+ assertModelName(sModelName);
3788
+ var oInfo = this._getObjectBindingInfo(sModelName);
3789
+ return oInfo && oInfo.binding;
4472
3790
  };
4473
3791
 
4474
3792
  /**
4475
3793
  * Returns the parent managed object as new eventing parent to enable control event bubbling
4476
3794
  * or <code>null</code> if this object hasn't been added to a parent yet.
4477
3795
  *
4478
- * @return {sap.ui.base.EventProvider} the parent event provider
3796
+ * @returns {sap.ui.base.EventProvider|null} the parent event provider
4479
3797
  * @protected
4480
3798
  */
4481
3799
  ManagedObject.prototype.getEventingParent = function() {
@@ -4483,10 +3801,10 @@ sap.ui.define([
4483
3801
  };
4484
3802
 
4485
3803
  /**
4486
- * Get the binding object for a specific aggregation/property
3804
+ * Get the binding object for a specific aggregation/property.
4487
3805
  *
4488
3806
  * @param {string} sName the name of the property or aggregation
4489
- * @return {sap.ui.model.Binding} the binding for the given name
3807
+ * @returns {sap.ui.model.Binding|undefined} the binding for the given name
4490
3808
  * @public
4491
3809
  */
4492
3810
  ManagedObject.prototype.getBinding = function(sName){
@@ -4495,10 +3813,10 @@ sap.ui.define([
4495
3813
  };
4496
3814
 
4497
3815
  /**
4498
- * Get the binding path for a specific aggregation/property
3816
+ * Get the binding path for a specific aggregation/property.
4499
3817
  *
4500
3818
  * @param {string} sName the name of the property or aggregation
4501
- * @return {string} the binding path for the given name
3819
+ * @return {string|undefined} the binding path for the given name
4502
3820
  * @protected
4503
3821
  */
4504
3822
  ManagedObject.prototype.getBindingPath = function(sName){
@@ -4531,9 +3849,9 @@ sap.ui.define([
4531
3849
  * @public
4532
3850
  */
4533
3851
  ManagedObject.prototype.setBindingContext = function(oContext, sModelName){
4534
- assert(sModelName === undefined || (typeof sModelName === "string" && !/^(undefined|null)?$/.test(sModelName)), "sModelName must be a string or omitted");
3852
+ assertModelName(sModelName);
4535
3853
  var oOldContext = this.oBindingContexts[sModelName];
4536
- if (Context.hasChanged(oOldContext, oContext)) {
3854
+ if (oOldContext !== oContext || oContext && oContext.hasChanged()) {
4537
3855
  if (oContext === undefined) {
4538
3856
  delete this.oBindingContexts[sModelName];
4539
3857
  } else {
@@ -4558,106 +3876,13 @@ sap.ui.define([
4558
3876
  * @param {string} [sModelName] the name of the model to set the context for or <code>undefined</code>
4559
3877
  * @private
4560
3878
  */
4561
- ManagedObject.prototype.setElementBindingContext = function(oContext, sModelName){
4562
- assert(sModelName === undefined || (typeof sModelName === "string" && !/^(undefined|null)?$/.test(sModelName)), "sModelName must be a string or omitted");
4563
- var oOldContext = this.mElementBindingContexts[sModelName];
4564
-
4565
- if (Context.hasChanged(oOldContext, oContext)) {
4566
- if (oContext === undefined) {
4567
- delete this.mElementBindingContexts[sModelName];
4568
- } else {
4569
- this.mElementBindingContexts[sModelName] = oContext;
4570
- }
4571
- this.updateBindingContext(true, sModelName);
4572
- this.propagateProperties(sModelName);
4573
- this.fireModelContextChange();
4574
- }
4575
- return this;
4576
- };
3879
+ ManagedObject.prototype.setElementBindingContext = function(oContext, sModelName) { };
4577
3880
 
4578
3881
  /**
4579
3882
  * Update the binding context in this object and all aggregated children
4580
3883
  * @private
4581
3884
  */
4582
- ManagedObject.prototype.updateBindingContext = function(bSkipLocal, sFixedModelName, bUpdateAll){
4583
-
4584
- var oModel,
4585
- oModelNames = {},
4586
- sModelName,
4587
- oContext,
4588
- sName,
4589
- oBindingInfo,
4590
- aParts;
4591
-
4592
- // Whether the binding part with the given index belongs to the current model name and is
4593
- // not a static binding
4594
- function isPartForModel(iPartIndex) {
4595
- return aParts[iPartIndex].model == sModelName && aParts[iPartIndex].value === undefined;
4596
- }
4597
-
4598
- // find models that need a context update
4599
- if (bUpdateAll) {
4600
- for (sModelName in this.oModels) {
4601
- if ( this.oModels.hasOwnProperty(sModelName) ) {
4602
- oModelNames[sModelName] = sModelName;
4603
- }
4604
- }
4605
- for (sModelName in this.oPropagatedProperties.oModels) {
4606
- if ( this.oPropagatedProperties.oModels.hasOwnProperty(sModelName) ) {
4607
- oModelNames[sModelName] = sModelName;
4608
- }
4609
- }
4610
- } else {
4611
- oModelNames[sFixedModelName] = sFixedModelName;
4612
- }
4613
-
4614
- for (sModelName in oModelNames ) {
4615
- if ( oModelNames.hasOwnProperty(sModelName) ) {
4616
- sModelName = sModelName === "undefined" ? undefined : sModelName;
4617
- oModel = this.getModel(sModelName);
4618
- oBindingInfo = this.mObjectBindingInfos[sModelName];
4619
-
4620
- if (oModel && oBindingInfo && !bSkipLocal) {
4621
- if (!oBindingInfo.binding) {
4622
- this._bindObject(oBindingInfo);
4623
- } else {
4624
- oContext = this._getBindingContext(sModelName);
4625
- if (Context.hasChanged(oBindingInfo.binding.getContext(), oContext)) {
4626
- oBindingInfo.binding.setContext(oContext);
4627
- }
4628
- }
4629
- continue;
4630
- }
4631
-
4632
- oContext = this.getBindingContext(sModelName);
4633
-
4634
- // update context in existing bindings
4635
- for ( sName in this.mBindingInfos ){
4636
- var oBindingInfo = this.mBindingInfos[sName],
4637
- oBinding = oBindingInfo.binding;
4638
-
4639
- aParts = oBindingInfo.parts;
4640
-
4641
- if (!oBinding) {
4642
- continue;
4643
- }
4644
- if (oBinding instanceof CompositeBinding) {
4645
- oBinding.setContext(oContext, {fnIsBindingRelevant : isPartForModel});
4646
- } else if (oBindingInfo.factory) {
4647
- // list binding: update required when the model has the same name (or updateall)
4648
- if ( oBindingInfo.model == sModelName) {
4649
- oBinding.setContext(oContext);
4650
- }
4651
-
4652
- } else if (isPartForModel(0)) {
4653
- // simple property binding: update required when the model has the same name
4654
- oBinding.setContext(oContext);
4655
- }
4656
- }
4657
- }
4658
- }
4659
-
4660
- };
3885
+ ManagedObject.prototype.updateBindingContext = function(bSkipLocal, sFixedModelName, bUpdateAll) { };
4661
3886
 
4662
3887
 
4663
3888
  /**
@@ -4870,6 +4095,9 @@ sap.ui.define([
4870
4095
  sAggregationName, oAggregation, i,
4871
4096
  mAllAggregations = Object.assign({}, this.mAggregations, this.mForwardedAggregations);
4872
4097
 
4098
+ // introduce data binding capabilities via mixin if available
4099
+ checkForBindingSupport(oProperties.oModels);
4100
+
4873
4101
  for (sAggregationName in mAllAggregations) {
4874
4102
  if (this.mSkipPropagation[sAggregationName]) {
4875
4103
  continue;
@@ -4898,6 +4126,10 @@ sap.ui.define([
4898
4126
  bUpdateListener = vName === false;
4899
4127
  sName = bUpdateAll ? undefined : vName;
4900
4128
  }
4129
+
4130
+ // introduce data binding capabilities via mixin if available
4131
+ checkForBindingSupport(oProperties.oModels);
4132
+
4901
4133
  if (oObject.oPropagatedProperties !== oProperties) {
4902
4134
  oObject.oPropagatedProperties = oProperties;
4903
4135
  // if propagation triggered by adding a listener no binding updates needed
@@ -4970,7 +4202,7 @@ sap.ui.define([
4970
4202
  * @public
4971
4203
  */
4972
4204
  ManagedObject.prototype.getModel = function(sModelName) {
4973
- assert(sModelName === undefined || (typeof sModelName === "string" && !/^(undefined|null)?$/.test(sModelName)), "sModelName must be a string or omitted");
4205
+ assertModelName(sModelName);
4974
4206
  return this.oModels[sModelName] || this.oPropagatedProperties.oModels[sModelName];
4975
4207
  };
4976
4208
 
@@ -5093,7 +4325,7 @@ sap.ui.define([
5093
4325
  sKey,
5094
4326
  sName,
5095
4327
  oClone,
5096
- escape = ManagedObject.bindingParser.escape,
4328
+ escape = BindingInfo.escape,
5097
4329
  i,
5098
4330
  oTarget;
5099
4331
 
@@ -5113,7 +4345,7 @@ sap.ui.define([
5113
4345
  vValue = oProperty.byValue ? deepClone(mProps[sKey]) : mProps[sKey];
5114
4346
  if (vValue && typeof vValue === "object" && !Object.isFrozen(vValue)) {
5115
4347
  //mark objects to not interpret it as bindingInfos
5116
- vValue[sUI5ObjectMarker] = true;
4348
+ vValue[BindingInfo.UI5ObjectMarker] = true;
5117
4349
  }
5118
4350
  mSettings[sKey] = vValue;
5119
4351
  }
@@ -5179,15 +4411,15 @@ sap.ui.define([
5179
4411
  * Clones the BindingInfo for the aggregation/property with the given name of this ManagedObject and binds
5180
4412
  * the aggregation/property with the given target name on the given clone using the same BindingInfo.
5181
4413
  *
5182
- * @param {sap.ui.base.ManagedObject} oSource Source of the clone operation
5183
- * @param {string} sName the name of the binding to clone
4414
+ * @param {sap.ui.base.ManagedObject.ObjectBindingInfo|sap.ui.base.ManagedObject.AggregationBindingInfo|sap.ui.base.ManagedObject.PropertyBindingInfo} oBindingInfo the original binding info
5184
4415
  * @param {sap.ui.base.ManagedObject} oClone the object on which to establish the cloned binding
5185
- * @param {string} sTargetName the name of the clone's aggregation to bind
4416
+ * @param {string} [sTargetName] the name of the clone's aggregation/property to bind, omitted for object bindings
4417
+ * @param {sap.ui.base.ManagedObject} [oSource] Source of the clone operation
4418
+ * @param {string} [sName] the name of the aggregation/property
5186
4419
  * @private
5187
4420
  */
5188
- function cloneBinding(oSource, sName, oClone, sTargetName) {
5189
- var oBindingInfo = oSource.mBindingInfos[sName];
5190
- oBindingInfo = oBindingInfo || oSource.getBindingInfo(sName); // fallback for forwarded bindings
4421
+ function cloneBinding(oBindingInfo, oClone, sTargetName, oSource, sName) {
4422
+ var bIsObjectBinding = !sTargetName;
5191
4423
  var oCloneBindingInfo = Object.assign({}, oBindingInfo);
5192
4424
 
5193
4425
  // clone the template if it is not sharable
@@ -5210,21 +4442,15 @@ sap.ui.define([
5210
4442
  delete oCloneBindingInfo.dataStateChangeHandler;
5211
4443
  delete oCloneBindingInfo.modelRefreshHandler;
5212
4444
 
5213
- if (oBindingInfo.factory || oBindingInfo.template) {
4445
+ if (bIsObjectBinding) {
4446
+ oClone.bindObject(oCloneBindingInfo);
4447
+ } else if (oBindingInfo.factory) {
5214
4448
  oClone.bindAggregation(sTargetName, oCloneBindingInfo);
5215
4449
  } else {
5216
4450
  oClone.bindProperty(sTargetName, oCloneBindingInfo);
5217
4451
  }
5218
4452
  }
5219
4453
 
5220
- /* Clone element bindings: Clone the objects not the parameters
5221
- * Context will only be updated when adding the control to the control tree;
5222
- * Maybe we have to call updateBindingContext() here?
5223
- */
5224
- for (sName in this.mObjectBindingInfos) {
5225
- oClone.mObjectBindingInfos[sName] = Object.assign({}, this.mObjectBindingInfos[sName]);
5226
- }
5227
-
5228
4454
  // Clone events
5229
4455
  for (sName in this.mEventRegistry) {
5230
4456
  oClone.mEventRegistry[sName] = this.mEventRegistry[sName].slice();
@@ -5232,8 +4458,12 @@ sap.ui.define([
5232
4458
 
5233
4459
  // Clone bindings
5234
4460
  if (bCloneBindings) {
4461
+ for (sName in this.mObjectBindingInfos) {
4462
+ cloneBinding(this.mObjectBindingInfos[sName], oClone);
4463
+ }
4464
+
5235
4465
  for (sName in this.mBindingInfos) {
5236
- cloneBinding(this, sName, oClone, sName);
4466
+ cloneBinding(this.mBindingInfos[sName], oClone, sName, this, sName);
5237
4467
  }
5238
4468
  }
5239
4469
 
@@ -5253,7 +4483,7 @@ sap.ui.define([
5253
4483
  if (oForwarder) {
5254
4484
  oTarget = oForwarder.getTarget(oClone, true);
5255
4485
  if (oForwarder.forwardBinding && this.isBound(sName)) { // forwarded bindings have not been cloned yet
5256
- cloneBinding(this, sName, oTarget, oForwarder.targetAggregationName);
4486
+ cloneBinding(this.getBindingInfo(sName), oTarget, oForwarder.targetAggregationName, this, sName);
5257
4487
  }
5258
4488
  }
5259
4489
  }