Search code examples
sapui5

VizFrame doesn't update when the bound model changes


I have a sap.viz.ui5.controls.VizFrame with its data property bound to a two-way JSON model in my view. Additionally, I have a Button and a Text element in the same view. The Text element displays the values of the model, which is bound against the VizFrame, and the Button has a press event handler, which increases the value of one property of the model.

So, when I press the button, the Text updates automatically, unlike the VizFrame. Do you have any suggestions on how to fix this? I saw this vizUpdate method, but it looked very complex and is probably overkill. However, changing the whole model also changes the displayed data of the VizFrame.

Code Example

Main.view.xml

<mvc:View controllerName="demo.chart.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m"
    xmlns:viz="sap.viz.ui5.controls" xmlns:viz.data="sap.viz.ui5.data" xmlns:viz.feeds="sap.viz.ui5.controls.common.feeds">
    <Shell id="shell">
        <App id="app">
            <pages>
                <Page id="page" title="{i18n>title}">
                    <content>
                        <VBox>
                            <viz:VizFrame id="vizFrame" uiConfig="{applicationSet:'fiori'}" vizType='donut'>
                                <viz:dataset>
                                    <viz.data:FlattenedDataset data="{data>/}">
                                        <viz.data:dimensions>
                                            <viz.data:DimensionDefinition name="Type" value="{manipulatedData>type}"/>
                                        </viz.data:dimensions>
                                        <viz.data:measures>
                                            <viz.data:MeasureDefinition name="Amount" value="{manipulatedData>amount}"/>
                                        </viz.data:measures>
                                    </viz.data:FlattenedDataset>
                                </viz:dataset>
                                <viz:feeds>
                                    <viz.feeds:FeedItem uid="color" type="Dimension" values="Type"/>
                                    <viz.feeds:FeedItem uid="size" type="Measure" values="Amount"/>
                                </viz:feeds>
                            </viz:VizFrame>
                            <Button text="+1 Foo" press="onButtonPress"/>
                            <Text text="Foo: {data>/0/amount} | Bar: {data>/1/amount}"/>
                        </VBox>
                    </content>
                </Page>
            </pages>
        </App>
    </Shell>
</mvc:View>

Main.controller.js

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/model/json/JSONModel"
], function (Controller, JSONModel) {
    "use strict";

    return Controller.extend("demo.chart.controller.Main", {
        onInit: function () {
            this.mData = new JSONModel([{
                type: "foo",
                amount: 23
            }, {
                type: "bar",
                amount: 20
            }]).setDefaultBindingMode("TwoWay");
            this.getView().setModel(this.mData, "data");
        },

        onButtonPress() {
            this.mData.setProperty("/0/amount", this.mData.getProperty("/0/amount") + 1);
        }
    });
});

Solution

  • I guess I figured it out. You have to rebind the data to the dataset aggregation after you changed the model:

    Working Example

    Main.controller.js

    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/ui/model/json/JSONModel"
    ], function (Controller, JSONModel) {
        "use strict";
    
        return Controller.extend("demo.chart.controller.Main", {
            onInit: function () {
                this.mData = new JSONModel([{
                    type: "foo",
                    amount: 23
                }, {
                    type: "bar",
                    amount: 20
                }]).setDefaultBindingMode("TwoWay");
                this.getView().setModel(this.mData, "data");
            },
    
            onButtonPress() {
                this.mData.setProperty("/0/amount", this.mData.getProperty("/0/amount") + 1);
                this.byId("vizFrame").getDataset().bindData({
                    path: "data>/"
                });
            }
        });
    });