Fiori应用二次进入第二视图时数据无法完全绑定问题求助
Fiori视图二次进入后数据绑定不完全问题
我的Fiori应用包含两个视图,从第一个视图导航至第二个视图后,会调用OData服务将数据绑定至JSONModel,再将该模型绑定到XML视图;完成create服务调用并结束交易后,用户返回第一个视图。当前遇到的问题是:完成一次交易后,当用户再次进入第二个视图时,数据无法完全绑定到视图上。
相关代码
XML视图代码
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m" controllerName="com.fm.zwmlabels.controller.ThirdPage" displayBlock="true"> <App id="idAppControl"> <pages> <Page title="{i18n>title}"> <content> <sap.ui.layout.form:SimpleForm xmlns:sap.ui.layout.form="sap.ui.layout.form" xmlns:sap.ui.core="sap.ui.core" editable="true" layout="ResponsiveGridLayout" id="form0" class="sapUiLargeMarginBegin"> <sap.ui.layout.form:content> <Label text="{i18n>MaterialNumber}" id="label0"/> <Input width="80%" value="{infoModel>/info/Material}" id="materialnumber" editable="false"/> <Label text="{i18n>PalletLabelNumber}" id="label1"/> <Input width="80%" value="{path : 'infoModel>/info/PalletLabelNumber' , formatter:'com.fm.zwmlabels.controller.formatter.removeLeadingZeroes'}" id="PalletLabelNumber"/> <Label text="{i18n>Noofpistonsperpallet}" id="label2"/> <Input width="80%" value="{path : 'infoModel>/info/pistonsperpallet', formatter:'com.fm.zwmlabels.controller.formatter.removeLeadingZeroes'}" id="Noofpistonsperpallet" editable="false"/> <Label text="{i18n>Noofboxlabels}" id="label3"/> <Input width="80%" id="Noofboxlabels" value="{path : 'infoModel>/info/Nrboxlabel', formatter:'com.fm.zwmlabels.controller.formatter.removeLeadingZeroes'}" editable="false"/> <Label text="{i18n>Noofpistonsperbox}" id="label4"/> <Input width="80%" value="{path : 'infoModel>/info/Nrpistonsbox', formatter:'com.fm.zwmlabels.controller.formatter.removeLeadingZeroes'}" id="Noofpistonsperbox" editable="false"/> <Label text="{i18n>Outputdevicepallet}" id="label5"/> <Input width="80%" value="{infoModel>/info/Outputdevpal}" id="Outputdevicepallet" showValueHelp="true" valueHelpOnly="true" valueHelpRequest="showOutputDeviceValueHelp"/> <Label text="{i18n>Outputdevicebox}" id="label6"/> <Input width="80%" id="Outputdevicebox" value="{infoModel>/info/Outputdevbox}" showValueHelp="true" valueHelpOnly="true" valueHelpRequest="showOutputDeviceValueHelp"/> <Label text="{i18n>Noofpalletlabels}" id="label7"/> <Input width="80%" value="{path : 'infoModel>/info/Noofpallab', formatter:'com.fm.zwmlabels.controller.formatter.removeLeadingZeroes'}" id="Noofpalletlabels"/> </sap.ui.layout.form:content> </sap.ui.layout.form:SimpleForm> </content> <footer> <Bar id="bar"> <contentRight> <Button id="_IDGenButton2" text="{i18n>Confirm}" type="Emphasized" tooltip="{i18n>Continue}" enabled="true" press="confirmPress"/> </contentRight> </Bar> </footer> </Page> </pages> </App> </mvc:View>
Controller代码
sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/Dialog", "sap/m/Button", "sap/m/Label", "sap/m/library", "sap/m/MessageToast", "sap/m/Text", "sap/m/TextArea", "com/fm/zwmlabels/controller/formatter", 'sap/ui/model/Filter', 'sap/ui/model/FilterOperator' ], function (Controller, Dialog, Button, Label, mobileLibrary, MessageToast, Text, TextArea, formatter, Filter, FilterOperator) { "use strict"; return Controller.extend("com.fm.zwmlabels.controller.ThirdPage", { onInit: function () { this.router = sap.ui.core.UIComponent.getRouterFor(this); this.router.attachRoutePatternMatched(this._handleRouteMatched, this); this.infoModel = new sap.ui.model.json.JSONModel(); this.getView().setModel(this.infoModel, "infoModel"); }, //调用服务并绑定数据至视图 callInformationSet: function () { var that = this; var oModel = this.getView().getModel(); this.defineBusyIndicator(oModel); oModel.refresh(); oModel.read("/ZLABEL_INFORMATIONSet('" + this.selectedVariant + "')", { success: function (oData, oResponse) { that.infoModel.setProperty("/info", oData); that.HUExists=oData.Huexist; that.callOutputDeviceData(); console.log(oData); }, error: function (error) { console.log(error); } }); }, callOutputDeviceData: function () { var oModel = this.getView().getModel(); this.defineBusyIndicator(oModel); var that = this; oModel.read("/OuputDevicePalletSearchHelpSet", { success: function (oData, oResponse) { that.infoModel.setProperty("/output", oData.results); console.log(oData); }, error: function (error) { console.log(error); } }); }, onConfirm: function () { var Material = this.getView().byId("materialnumber") var PalletLabelNumber = this.getView().byId("PalletLabelNumber"); var pistonsperpallet = this.getView().byId("Noofpistonsperpallet"); var boxlabels = this.getView().byId("Noofboxlabels"); var pistonsperbox = this.getView().byId("Noofpistonsperbox"); var outputdevicepallet = this.getView().byId("Outputdevicepallet"); var outputdevicebox = this.getView().byId("Outputdevicebox"); var palletlabels = this.getView().byId("Noofpalletlabels"); if (this.checkEmptyValues(Material)===1 && this.checkEmptyValues(PalletLabelNumber)===1 && this.checkEmptyValues(pistonsperpallet)===1 && this.checkEmptyValues(boxlabels)===1 && this.checkEmptyValues(pistonsperbox)===1 && this.checkEmptyValues(outputdevicepallet)===1 && this.checkEmptyValues(outputdevicebox)===1 && this.checkEmptyValues(palletlabels)=== 1) { var data = {}; data.Material = Material.getValue(); data.BapiMsg = ""; data.Variant = this.selectedVariant; data.PalletLabelNumber = PalletLabelNumber.getValue(); data.pistonsperpallet = pistonsperpallet.getValue(); data.Nrboxlabel = boxlabels.getValue(); data.Nrpistonsbox = pistonsperbox.getValue(); data.Outputdevpal = outputdevicepallet.getValue(); data.Outputdevbox = outputdevicebox.getValue(); data.Noofpallab = palletlabels.getValue(); var that = this; var oModel = this.getView().getModel(); oModel.create("/ZLABEL_INFORMATIONSet", data, { success: function (oData, oResponse) { if (oData.BapiMsg.length !== 0) { that._showSuccess(oData.BapiMsg); } }, error: function (error) { that._oBusyDialog.close(); that._showSendFailure("", error); } }); } else return; }, checkEmptyValues : function(elementId) { if(elementId.getValue()==="") { elementId.setValueState("Error"); return 0; } else { elementId.setValueState("None"); return 1; } }, onResetPress : function() { this.getView().byId("materialnumber").setValue(""); this.getView().byId("PalletLabelNumber").setValue(""); this.getView().byId("Noofpistonsperpallet").setValue(""); this.getView().byId("Noofboxlabels").setValue(""); this.getView().byId("Noofpistonsperbox").setValue(""); this.getView().byId("Outputdevicepallet").setValue(""); this.getView().byId("Outputdevicebox").setValue(""); this.getView().byId("Noofpalletlabels").setValue(""); } }); });
问题排查与解决方案
1. JSONModel未重置导致旧数据残留
每次进入视图时,infoModel未被清空,旧数据会干扰新数据绑定(尤其是新OData返回字段不全时,旧字段会保留)。
- 解决:在路由匹配方法
_handleRouteMatched中先重置模型:_handleRouteMatched: function(oEvent) { this.selectedVariant = oEvent.getParameter("arguments").selectedVariant; // 清空模型数据 this.infoModel.setData({}); // 重新拉取数据 this.callInformationSet(); }
2. 控件绑定未强制刷新
部分带formatter的控件,模型更新时formatter可能未触发,导致显示旧值。
- 解决:在
callInformationSet的success回调中强制刷新绑定:success: function (oData, oResponse) { that.infoModel.setProperty("/info", oData); that.HUExists = oData.Huexist; that.callOutputDeviceData(); // 强制刷新视图绑定 that.getView().getBindingContext("infoModel")?.refresh(true); console.log(oData); }
3. OData模型缓存问题
OData模型默认开启缓存,第二次调用read可能返回缓存数据,未获取最新值。
- 解决:调用read时添加
refresh: true参数:oModel.read("/ZLABEL_INFORMATIONSet('" + this.selectedVariant + "')", { success: function (oData, oResponse) { /* ... */ }, error: function (error) { /* ... */ }, refresh: true // 强制从服务器拉取最新数据 });
4. 重置方法未同步模型数据
当前onResetPress仅清空控件值,未重置infoModel,导致模型与视图状态不一致。
- 解决:修改重置方法,同步清空模型:
onResetPress : function() { // 清空控件值 this.getView().byId("materialnumber").setValue(""); this.getView().byId("PalletLabelNumber").setValue(""); this.getView().byId("Noofpistonsperpallet").setValue(""); this.getView().byId("Noofboxlabels").setValue(""); this.getView().byId("Noofpistonsperbox").setValue(""); this.getView().byId("Outputdevicepallet").setValue(""); this.getView().byId("Outputdevicebox").setValue(""); this.getView().byId("Noofpalletlabels").setValue(""); // 重置模型数据 this.infoModel.setProperty("/info", {}); }
5. 修复代码语法错误
原onInit方法中有多余的t字符,需删除避免语法错误。
内容的提问来源于stack exchange,提问作者Swappy
相关产品推荐
相关产品推荐

