openui5 icon indicating copy to clipboard operation
openui5 copied to clipboard

ManagedObject: "objectBindings" support in XML view / fragment definitions

Open boghyon opened this issue 5 years ago • 5 comments

URL (minimal example if possible)

https://jsbin.com/hopizef/edit?html,js,output

Given

<MyControl objectBindings="{
  myModel: { path: '/someObject' },  
  myAnotherModel: { path: '/objectFromAnotherModel' }
}" />

What is the expected result?

ManagedObject calls bindObject according to the API contract for each key without any issues. https://github.com/SAP/openui5/blob/ca82db0229de26dec2fc554353838ad8e6fc5401/src/sap.ui.core/src/sap/ui/base/ManagedObject.js#L1150-L1153

What happens instead?

The only place in the XMlTemplateProcessor, where objectBindings is handled, is this one: https://github.com/SAP/openui5/blob/ca82db0229de26dec2fc554353838ad8e6fc5401/src/sap.ui.core/src/sap/ui/core/XMLTemplateProcessor.js#L803-L809 But that results in the following objectBindings object:

{
  undefined: {
    myAnotherModel: { path: "/objectFromAnotherModel" },
    myModel: { path: "/someObject" }
  }
}

which is passed to ManagedObject settings: https://github.com/SAP/openui5/blob/ca82db0229de26dec2fc554353838ad8e6fc5401/src/sap.ui.core/src/sap/ui/base/ManagedObject.js#L1142-L1155

And since the key is undefined, the browser throws an uncaught TypeError.

Any other information? (attach screenshot if possible)

After reading https://github.com/SAP/openui5/issues/544, I thought objectBindings is supported at least in fragments but there it fails too.


Also the description of objectBindings in the API reference ...

objectBindings : object A map of binding paths keyed by the corresponding model name. Each entry with key k in this object has the same effect as a call this.bindObject(objectBindings[k], k);.

... is a bit weird to me since bindObject awaits an object as the only argument. But according to the description above, this.bindObject(path, modelName) will be called. In the real code, on the other hand, it's this.bindObject(bindingInfo) again.src

boghyon avatar Apr 15 '20 20:04 boghyon

Multiple object bindings are just not supported in the XMLView. It's more by accident that BindingParser returns something when given a map of bindings. It doesn't really handle it.

The description of bindObject is not so weird, when you look at the code in lines 3028-3037. Those lines handle a legacy form of the bindObject method that accepted a path. Nevertheless, the description is outdated and I can't find any hint that the suggested 2nd parameter for the model name ever existed (although it would have been consistent with the setModel API).

I leave the issue open for the dispatcher to create an incident. Colleagues can check whether support for multiple bindings is something for our roadmap or not and the documentation in ManagedObject should be updated, anyhow.

codeworrior avatar Apr 15 '20 21:04 codeworrior

Yeah, I wasn't sure whether objectBindings is even supported by XMLViews or not. It would be nice if it could, to allow binding multiple contexts declaratively. I was also inspired by @rpbouman's question, where objectBindings would've been perfect.

boghyon avatar Apr 16 '20 10:04 boghyon

Hi @boghyon, @codeworrior I didn't know this objectBindings attribute. Wonderful, I will look into it.

Re. my question on multiple bindings: yeah this is not just some theoretical example. I am building what I consider a large and fairly complex ui5 app, and I really do need multiple models and lots of reusable fragments to keep things manageable. To maximize reusability of fragments, I really do need this "relative" binding and resolution based on the container, but I do not want to put the code to bind the containers in my code.

It feels a bit random that we can achieve it in code, and not from the XML.

One could wonder how to solve things syntactically as XML requires unique attribute names per element. As I mentioned in a comment on my post, I would be happy if I could achieve this using the "parts" syntax, but this doesn't seem to work.

<m:TabContainer
  binding="{
    parts: [{path: 'B>/K/L/M'},{path: 'A>/X'}]
  }"
>

While we are at it: if we could do aggregate binding from within the XML with parts/formatter syntax, which works really well for property binding, then it would solve a lot of other problems for me.

Concrete cases is where I receive some data which I want to use to drive aggregations. As always the data I receive is very far from the format the aggregation wants and needs. So usually I transform the data when I receive it into whatever format I need for the aggregation and store the result in the model. But this case feels a lot like what we have for property binding where we would use a formatter. I would like to do that for aggregations as well - transform the data on the fly and only as needed, as property of the binding, so I can keep the model clean and only store the actual data.

rpbouman avatar Apr 19 '20 09:04 rpbouman

Hello @boghyon ,

Thank you for sharing your enhancement proposal. I've created an internal incident 2080221780. The status of the issue will be updated here in GitHub.

Regards, Florian

flovogt avatar Jun 25 '20 08:06 flovogt

Hi @boghyon, we've discussed your enhancement proposal and agreed on implementing it. The BLI is CPOUI5FRAMEWORK-122. This issue will be updated when the BLI is implemented. Best Regards, Florian

flovogt avatar Jul 17 '20 11:07 flovogt