Reputation: 9525
I have a parent - child relationship in a JSON model. I have a view that lists the parents using an ObjectList. The press event of an item in this list navigates to another view where a similar ObjectList shows the children of the selected parent.
I want to be able to make the title of the view displaying the children include an attribute of the parent. For example, if the model is:
{
"parents": [
{
"name": "Spartacus","children": [{"name": "Spartacus Jnr"}, {"name": "Little Spartacus"}]
},
{"name": "Rasputin", "children": [{"name": "Grigori"}, {"name": "Yefimovich"}]
},
{"name": "Sting", "children": [{"name": "Josepth"}, {"name": "Fuchsia"}]}
]
}
Then if I select parent 'Spartacus' then the view showing the children should have as a title Children of Spartacus
.
Important: For various reasons I have the child view bound to the children array. If I bound the child view to the parent and set the ObjectList path to /children
then this would solve my problem. I could also get the path for the objectContext of the view and chop it up and retrieve the parent value that way - but that feels clunky and anyway I use XML view declaration. Overall I am stubborn and curious and want to know about upward traversal using relative paths.
I have tried a relative path approach using double-dots as one would in, for example, xpath:
headerText="Children of {../name}"
But this does not work. I have found much to explain bindings in UI5 but nothing discussing traversing up the model as is required here. Can anyone help with a solution or a link to docs that give a solution?
Upvotes: 0
Views: 921
Reputation: 9525
My own workaround is to contrive to get the parent name in the controller for the children view, then use
var list = this.byId("ChldrenList")
list.setHeaderText('Children for ' + mdlParent.name)
// where mdlParent.name is my arbitrary model and attribute to be displayed.
I remain unhappy with this as it dilutes the power of the declarative XML view approach. But my boss says to suck it up and move on 8-)
Upvotes: 0
Reputation: 4231
The default JSONBinding implementation does not support path traversal. However it is possible to easily solve your issue, by setting a different binding context where it is needed. I created an example simulating this. The items aggregation of the list containing the children is directly bound to the children array:
let path = "/parents/0";
let childrenTable = this.byId("children");
childrenTable.bindAggregation("items", {
"path" : path + "/children",
"template" : new StandardListItem({ "title" : "{name}"})
});
To show the name of the parent, I added a toolbar to the list and bind it to the corresponding parent in the model.
childrenTable.getAggregation("headerToolbar").bindElement(path);
Upvotes: 0
Reputation: 76
If this were OData you could have a link to the parent inside the child objects and refer to it through that but as far as I am aware, there is no upwards relationship like this for a JSONModel.
You have really answered your own question here. What you want to do is bind the view to the parent and reference the children with the relative path. I don't see this as chunky. What is the disadvantage? You would still be loading the same data in the model and it is still organised in a logical fashion.
In fact, (to diverge a little) loading an oDataModel like I have mentioned above would be adding repeated values to the model with no obvious advantage when the view could have just been bound differently.
Upvotes: 1