Search code examples
sapui5

Event Handler for JSONModel Change?


Say, there's an sap.m.table whose items are bound to a JSON model - "/rows". Outside sap.m.table layout, there's a toolbar that contains "Add" button to add rows to the table. "Add" button adds rows to the table using model's setProperty method. Now, the requirement is to disable "Add" button when JSON model "/rows" length has reached 10. How do we create a handler to observe the changes of JSON model's "/rows" property? https://sapui5.netweaver.ondemand.com/1.52.22/#/api/sap.ui.model.Model/events/propertyChange states that Currently the event is only fired with reason sap.ui.model.ChangeReason.Binding which is fired when two way changes occur to a value of a property binding. This means that the eventHandler of propertyChange doesn't get triggered when JSONModel's setProperty() is called. Is there a way out where we can observe the changes of JSONModel's property changes - in this case, "/rows" property of the JSONModel?


Solution

  • Well I can think of several ways to achieve this

    1. Standard view binding + formatter:

    View

    ...
    <Button text="Add" press="onPressAdd" enabled="{path: '/rows', formatter: '.isAddEnabled'}" />
    ...
    

    Controller:

    Controller.prototype.isAddEnabled = function(rows) {
        return rows && rows.length < 10;
    }
    

    2. Expression binding (pure xml)

    ...
    <Button text="Add" press="onPressAdd" enabled="{= ${/rows/length} &lt; 10 }" />
    ...
    

    3. JSONPropertyBinding (pure javascript)

    You can call bindProperty on JSONModel to create a property binding that can be observed for changes:

    https://sapui5.hana.ondemand.com/#/api/sap.ui.model.Model/methods/bindProperty https://sapui5.hana.ondemand.com/#/api/sap.ui.model.json.JSONPropertyBinding

    Controller.prototype.onInit = function() {
        var model = this.getMyJsonModel();
        var button = this.getView().byId("myButtonId");
    
        model.bindProperty("/rows").attachChange(function(event) {
            button.setEnabled(event.getSource().getValue().length < 10);
        })
    }