Search code examples
xmlviewsapui5formatter

UI5 - Formatters in XML fragment are executed only once. How to run them again?


When a sap.ui.xmlfragment is rendered by UI5, formatters are executed only once and their results are cached. Then the dialog is closed ( dialog.close() ), user changes for example language, and runs the dialog again ( dialog.open() ).

But formatters are not evaluated again and therefore the previous state is shown.

How can I force them to be executed again?

My XML looks like this:

<Label text="{path: 'myModel>', formatter: '.myMethodInController'}"/>

And formatter:

myMethodInController: function(myObject){
  if (myObject.a == 1 || myObject.b == 2)
  {
    return myObject.c;
  }
  else
  {
    return myObject.d;
  }
}

Solution

  • One way is indeed what saoirse suggested in their answer. The sap.ui.model.Model#refresh with no parameters will trigger an update of the bound properties and hence recall the formatters if the bound data has changed. If you want the formatter to be called again even if the model data is the same (but maybe some controller property has changed), then you can pass a true flag to the refresh method: oModel.refresh(true). This parameter has the following function:

    bForceUpdate - Update controls even if data has not been changed

    Also, another version to solve your problem, assuming that you are changing just model data using two-way bindings or setProperty calls, is to do a composite binding on each primitive model property that you use:

    View:

    <Label text="{
        parts: [
             {path: 'myModel>/a'}, 
             {path: 'myModel>/b'}, 
             {path: 'myModel>/c'}, 
             {path: 'myModel>/d'}
        ], 
        formatter: '.myMethodInController'}"/>
    

    Formatter:

    myMethodInController: function(a, b, c, d){
      if (a == 1 || b == 2) {
        return c;
      } else {
        return d;
      }
    }
    

    The reason why this is automatically updated on change is the following: change is detected using a shallow comparison. The reference of the data object of your model does not change in your example (only the component values change), so no change is detected. In my version, each primitive component is monitored individually and a change to one value will trigger an update due to the binding mechanism (and thus re-call your formatter).