taavilooke
taavilooke

Reputation: 145

Is it possible to add Binding change event to a component in XML view?

I have a component in SAPUI5 where I need to listen to changes in the binding (Binding.change event). At the moment I'm adding a listener to the Binding in modelContextChange like this:

function onModelContextChange(oEvent){
   var oSelect = oEvent.getSource();
   var binding = oSelect.getBinding("items");
   if(binding){
      binding.attachChange(onDataChange, oSelect);
   }
}

However this causes all kinds of weird problems, because modelContextChange could be fired multiple times. It would be better to to this in the XML view. I've tried code like this, but it doesn't work.

<Select items="{ path: 'project>/data/', change:'onDataChange' templateShareable: false">
   <core:Item key="{project>Id}" text="{project>Parameter}"/>
</Select>

Any recommendations how to do this?

Upvotes: 0

Views: 9435

Answers (4)

Matthias G&#252;nter
Matthias G&#252;nter

Reputation: 637

I just came across the problem, too. I solved it in that way:

<Select items="{
  path: 'project>/data',
  events: {
    change: '.onDataChange'
  },
  templateShareable: false
}">

You can pass an events object to the binding and use the available bindings (e.g. v2.ODataListBinding). Note that you have to use a dot before your function name (.onDataChange). In your controller you can add the function:

onDataChange: function(oEvent) {
  // Your implementation...
},

Upvotes: 3

taavilooke
taavilooke

Reputation: 145

I managed to get the binding change event with this set to the element that I needed by attaching a modelContextChange to the element and handling attaching the change event to the binding in there. Here's the code from the view controller:

modelContextChange: function(oEvent) {
  var oElement = oEvent.getSource();
  var binding = oElement.getBinding("items");
  if (binding) {
    //Binding change event could already be attached, detach it first, if it's there
    binding.detachChange(this.onBindingChange, oSelect);
    binding.attachChange(this.onBindingChange, oSelect);
    // Beacause I used this inside a sap.ui.table.Treetable,
    // in some cases binding changes occur without the binding change event firing.
    // Manually fire the binding change just in case
    // YMMV
    binding.refresh(true);
  }
},
onBindingChange: function() {
  //The code that needs to run at binding change
  //"this" is set to the correct element 
  //I specifically needed to add one element in front of other items in a sap.m.Select
  var items = this.removeAllItems();
  this.addItem(new sap.ui.core.Item({
    key: 0,
    text: "< Inherit >"
  }));
  items.forEach(function(item) {
    this.addItem(item);
  }, this);
}

Upvotes: 0

If I remember well from the JS Views, I think it is like this:

<Select items="{ path: 'project>/data/', events: {change:'onDataChange'}, templateShareable: false}">

This is for listening to the Model "change" events.

If you want to listen to the "change" event in the Select control, this is when the user selects a different value in the dropdown, it is like this:

<Select items="{ path: 'project>/data/', templateShareable: false}" change="onDataChange">

EDIT: Using "modelContextChange" event.

<Select items="{ path: 'project>/data/', templateShareable: false}" modelContextChange="onDataChange">

Upvotes: 1

D. Seah
D. Seah

Reputation: 4592

here is an example

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>JS Bin</title>
    <script 
            src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" 
            id="sap-ui-bootstrap" 
            data-sap-ui-theme="sap_bluecrystal" 
            data-sap-ui-xx-bindingSyntax="complex" 
            data-sap-ui-libs="sap.m"></script>
    <style type="text/css">
      .sapMObjLTitle {
        cursor: pointer;
      }
    </style>

    <!-- XML-based view definition -->
    <script id="oView" type="sapui5/xmlview">
    <mvc:View height="100%" controllerName="myView.Template"
      xmlns="sap.m"
      xmlns:core="sap.ui.core"
      xmlns:mvc="sap.ui.core.mvc">
      <Select change="onDataChange" items="{ path: 'project>/data', templateShareable: false}">
        <core:Item key="{project>Id}" text="{project>Parameter}"/>
      </Select>
    </mvc:View>
    </script>

  </head>
  <body class="sapUiBody">
    <div id='content'></div>
  </body>
</html>


sap.ui.define([
  'jquery.sap.global',
  'sap/ui/core/mvc/Controller',
  'sap/ui/model/json/JSONModel'
], function(jQuery, Controller, JSONModel) {

  var ListController = Controller.extend("myView.Template", {
    onInit: function(oEvent) {
      var oView = this.getView();
      oView.setModel(new JSONModel({
        data: [{
          Id: "1",
          Parameter: "One" 
        }, {
          Id: "2",
          Parameter: "Two" 
        }]
      }), "project");
    },
    onDataChange: function() {
      alert("changed")
    }
  });

  return ListController;
});

// Instantiate the View and display
var oView = sap.ui.xmlview({
  viewContent: jQuery('#oView').html()
});

oView.placeAt('content');

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

Note: the change attribute in your XML is incorrect

Upvotes: 0

Related Questions