Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
671 views
in Technique[技术] by (71.8m points)

data binding - UI5: Formatter called multiple times or too soon from an XML view

I'm using OpenUI5. Using the formatter.js, I have formatted some text in my view.

But my formatter is called 3 times:

  1. When I bind the model to panel control: oPanel.setModel(oModel, "data"); both sBirthday and sFormat are undefined.

  2. After onInit() is finished and the view is rendered: sBirthday is valorized correctly and sFormat is undefined

  3. Again: both sBirthday and sFormat ara valorized correctly.

Why does this happen? Is it correct?
The app get an error, because the ageDescription() in the formatter, can't manage undefined values.

formatter.js

sap.ui.define([], function () {
  "use strict";

  return {
    ageDescription : function (sBirthday, sFormat) {
      do.something();
      var sFromMyBd = moment(sBirthday, sFormat).fromNow();
      do.something();
      return sAge;
    }
  }
});

main.view.xml

<mvc:View
  controllerName="controller.main"
  xmlns="sap.m"
  xmlns:mvc="sap.ui.core.mvc">
  <Panel id="user-panel-id">
    <Input id="name-input-id" enabled="false" value="{data>/user/name}" />
    <Label text="{i18n>age}: " class="sapUiSmallMargin"/>
    <Label text="{
      parts: [
        {path: 'data>/user/birthday'},
        {path: 'data>/user/dateFormat'}
      ],
      formatter: '.formatter.ageDescription' }"/>
  </Panel>
</mvc:View>

Main.controller.js

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

  return Controller.extend("controller.main", {
    formatter: formatter,
    onInit: function () {
      var oModel = new JSONModel();
      var oView = this.getView();
      oModel.loadData("model/data.json");
      var oPanel = oView.byId("user-panel-id");
      oPanel.setModel(oModel,"data");
      do.something();
    },
  });
});

data.json

{
  "user": {
    "name": "Frank",
    "surname": "Jhonson",
    "birthday": "23/03/1988",
    "dateFormat": "DD/MM/YYYY",
    "enabled": true,
    "address": {
      "street": "Minnesota street",
      "city": "San Francisco",
      "zip": "94112",
      "country": "California"
    }
  }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
  • Set the model to the view only when the data request is completed:

    onInit: function() {
      const dataUri = sap.ui.require.toUri("<myNamespace>/model/data.json");
      const model = new JSONModel(dataUri);
      model.attachEventOnce("requestCompleted", function() {
        this.getView().setModel(model);
      }, this);
      // ...
    },
    

    This ensures that the formatter is called only once (invoked by checkUpdate(true) which happens on binding initialization; see below), and no further changes are detected afterwards.

  • Additionally (or alternatively), make the formatter more defensive. Something like:

    function(value1, value2) {
      let result = "";
      if (value1 && value2) {
        // format accordingly ...
      }
      return result;
    }
    

Why does this happen?

  1. View gets instantiated.
  2. onInit of the Controller gets invoked. Here, the file model/data.json is requested (model is empty).
  3. Upon adding the view to the UI, UI5 propagates existing parent models to the view.
  4. Bindings within the view are initialized, triggering checkUpdate(/*forceUpdate*/true)src in each one of them.
  5. Due to the forceUpdate flag activated, change event is fired, which forcefully triggers the formatters even if there were no changes at all:
    [undefined, undefined][undefined, undefined]. - 1st formatter call
  6. Fetching model/data.json is now completed. Now the model needs to checkUpdate again.
  7. [undefined, undefined][value1, undefined] → change detected → 2nd formatter call
  8. [value1, undefined][value1, value2] → change detected → 3rd formatter call

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...