OData V2 在onInit阶段为DataSet设置属性时绑定上下文未定义的问题解决
问题根因
你遇到self.getView().getBindingContext()返回undefined,本质是两个问题叠加:
- 异步流程完全没做顺序管控:onInit里两个异步操作没有任何先后约束
一个是等模型元数据加载完成后,给视图绑定DataSet实体路径,这个过程从元数据就绪、到实体数据加载完成、再到把绑定上下文挂到视图上,本身是慢操作,耗时不稳定;另一个是请求CharSet接口,拿到响应就直接调onStartSetVisibilities。只要CharSet接口的响应比视图绑上下文的速度快,执行onStartSetVisibilities的时候视图根本还没生成绑定上下文,自然取不到sPath。 - 代码本身有硬语法/逻辑错误
- 取char值的路径没拼绑定上下文,直接从模型根节点找
GeneralData/Char,根本拿不到对应DataSet下的正确值 - 条件判断
char !== "" || char !== null是逻辑或,不管char是什么值这个条件都恒成立,完全不符合预期 - 代码里用了排版错位的特殊引号(
„GeneralData/Char"),实际执行会直接报语法错
- 取char值的路径没拼绑定上下文,直接从模型根节点找
修复方案
- 把异步流程的顺序对齐,别让逻辑跑在上下文前面
把原来零散的异步逻辑收敛,等视图成功绑定DataSet、对应实体数据加载完成之后,再去读CharSet、再做可见性属性设置。同时把绑定的对象路径提前存在控制器实例上,后面操作属性的时候不用再从视图反复取,从根源上避免拿空上下文:onInit: function () { const startupParameters = this.getOwnerComponent().getComponentData().startupParameters; const sWorkitem = startupParameters.TASK[0]; const oModel = this.getOwnerComponent().getModel(); this.setModel(oModel); oModel.metadataLoaded().then(() => { const sObjectPath = oModel.createKey("DataSet", { Workitem: sWorkitem }); // 把绑定路径存在控制器上,后续直接复用 this.sDataSetFullPath = "/" + sObjectPath; this.getView().bindElement({ path: this.sDataSetFullPath, events: { // 等实体数据加载完成、上下文真正挂到视图上之后,再触发后续逻辑 dataReceived: () => { oModel.read("/CharSet", { success: (response) => { $.sap.Chars = response.results; this.onStartSetVisibilities(oModel); } }); } } }); }.bind(this)); } - 修正onStartSetVisibilities的错误逻辑
去掉多余的self传参,直接用控制器存好的路径取值、设值,修正原来的逻辑错误和语法问题:onStartSetVisibilities: function (model) { // 从绑定的DataSet路径下取Char属性,不再无根取值 const char = model.getProperty(this.sDataSetFullPath + "/GeneralData/Char"); // 把原来的逻辑或改成逻辑与,确保char确实非空时再走设置逻辑 if (char !== "" && char !== null) { model.setProperty( this.sDataSetFullPath + "/Responsible", this.getResponsibleForChar(char) ); } } - 你的视图表达式绑定本身不需要改,只要
Responsible属性值按上面的流程正确写入模型,ObjectPageSubSection的visible状态就会自动响应更新。
兜底备选
如果因为业务逻辑特殊没法做时序对齐,原来注释的attachAfterRendering可以当兜底,但一定要加一次性触发的机制,避免视图重复渲染时反复跑属性设置逻辑:
注意:这种方式会比主动回调的方案晚一个渲染周期,首次加载时SubSection会出现短暂的显示/隐藏闪烁,优先推荐前面的时序对齐方案,尽量不要用这个兜底。
内容的提问来源于stack exchange,提问作者LoopAt
相关产品推荐
相关产品推荐

