我正在使用OpenUI5。使用formatter.js
,我在视图中格式化了一些文本。
但是我的格式化程序被调用了3次:
当我将模型绑定到面板控件时:oPanel.setModel(oModel, "data");
sBirthday
和sFormat
均为undefined
。
onInit()
完成并呈现视图之后:
sBirthday
已正确定价,sFormat
是undefined
再次:sBirthday
和sFormat
均正确地得到了估价。
为什么会这样?正确吗?
该应用出现错误,因为格式化程序中的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"
}
}
}
答案 0 :(得分:2)
仅在数据请求完成时将模型设置为视图:
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;
}
为什么会这样?
onInit
被调用。在此,请求文件model/data.json
(模型为空)。checkUpdate(/*forceUpdate*/true)
src 。forceUpdate
标志,因此触发了change
事件,即使没有任何更改,它也会强制触发格式化程序:[undefined, undefined]
→[undefined, undefined]
。 -第一个格式化程序调用model/data.json
现已完成。现在,该模型需要再次checkUpdate
。[undefined, undefined]
→[value1, undefined]
→检测到更改→第二次格式化程序调用[value1, undefined]
→[value1, value2]
→检测到更改→第三次格式化程序调用答案 1 :(得分:0)
现在,考虑到您试图将静态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.json
和oView
一开始就已经可见。
这样,格式化程序是否被多次调用无关紧要,因为它从一开始就已经有可用的数据。