UI5:从XML视图多次调用格式化程序或过早

我正在使用OpenUI5。使用formatter.js,我在视图中格式化了一些文本。

但是我的格式化程序被调用了3次:

  1. 当我将模型绑定到面板控件时:oPanel.setModel(oModel,"data"); sBirthdaysFormat均为undefined

  2. onInit()完成并呈现视图之后: sBirthday已正确定价,sFormatundefined

  3. 再次:sBirthdaysFormat均正确地得到了估价。

为什么会这样?正确吗?
该应用出现错误,因为格式化程序中的ageDescription()无法管理undefined的值。

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"
    }
  }
}
vrfriends 回答:UI5:从XML视图多次调用格式化程序或过早

  • 仅在数据请求完成时将模型设置为视图:

    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);
      // ...
    },

    这确保格式化程序仅被调用一次(由checkUpdate(true)调用,该操作在绑定初始化时发生;请参见下文),并且此后未检测到进一步的更改。

  • (可选)使格式化程序更具防御性。像这样:

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

  

为什么会这样?

  1. 视图被实例化。
  2. 控制器的
  3. onInit被调用。在此,请求文件model/data.json(模型为空)。
  4. 将视图添加到UI后,UI5传播现有父对象 建模到视图。
  5. 初始化视图中的绑定,并在每个视图中触发checkUpdate(/*forceUpdate*/true) src
  6. 由于激活了forceUpdate标志,因此触发了change事件,即使没有任何更改,它也会强制触发格式化程序:
    [undefined,undefined][undefined,undefined]。 -第一个格式化程序调用
  7. 获取model/data.json现已完成。现在,该模型需要再次checkUpdate
  8. [undefined,undefined][value1,undefined]→检测到更改→第二次格式化程序调用
  9. [value1,value2]→检测到更改→第三次格式化程序调用
,

现在,考虑到您试图将静态JSON文件加载到项目中,最好最大化manifest.json的使用率。

这样,您可以确定在进行任何绑定之前,数据已经在模型中加载并可用。

您可以通过将JSON文件添加为 sap.app

下的数据源来实现此目的。

manifest.json

"sap.app": {
    "id": "com.sample.app","type": "application","dataSources": {
        "data": {
            "type": "JSON","uri": "model/data.json"
        }
    }
}

现在,只需在 sap.ui5 下将名为dataSource的{​​{1}}添加为data之一即可。

models

有了这个,您不需要再打电话了

"sap.ui5": {
    "rootView": {
        "viewName": "com.sample.app.view.App","type": "XML"
    },"models": {
        "i18n": {
            "type": "sap.ui.model.resource.ResourceModel","settings": {
                "bundleName": "com.app.sample.i18n.i18n"
            }
        },"data": {
            "type": "sap.ui.model.json.JSONModel","dataSource": "data"
        }
    }
}

..就像我们在var oModel = new JSONModel(); var oView = this.getView(); oModel.loadData("model/data.json"); var oPanel = oView.byId("user-panel-id"); oPanel.setModel(oModel,"data"); 中添加的data model一样,manifest.jsonoView一开始就已经可见。

这样,格式化程序是否被多次调用无关紧要,因为它从一开始就已经有可用的数据。

本文链接:https://www.f2er.com/3125281.html

大家都在问