You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fiori Elements片段扩展中无需location.reload()刷新上下文方案

问题场景

在Fiori Elements应用中采用片段扩展(非传统UI5控制器),通过OData v4绑定实现了onSavePress函数用于数据更新/创建。保存后导航至ListReport的其他条目时,仍显示陈旧数据,目前仅location.reload()能解决,但需要更优方案。

简化代码实现

onSavePress: async function (oEvent) {
  const oButton = oEvent.getSource();
  const oVBox = oButton.getParent().getParent(); // Root container
  const oModel = oButton.getModel();
  const oCtx = oVBox.getBindingContext();
  const sId = oCtx.getObject().prod_nbr;

  const sPath = `/Products('${sId}')/general_info`;
  const oBinding = oModel.bindContext(sPath, null, {
    $$updateGroupId: "auto"
  });

  await oBinding.initialize();
  const oGenCtx = oBinding.getBoundContext();
  const generalInfo = await oGenCtx.requestObject();

  if (generalInfo) {
    oGenCtx.setProperty("color", "Red");
    oGenCtx.setProperty("notes", "Updated notes");
  } else {
    const oListBinding = oModel.bindList("/GeneralInfo", null, [], [], {
      $$updateGroupId: "auto"
    });
    oListBinding.create({
      ib_code: sId,
      color: "Red",
      notes: "Created"
    });
  }

  await oModel.submitBatch("auto");

  // TEMP workaround:
  location.reload(); // <- Without this, context doesn't refresh properly
}

面临挑战

  • 未使用标准控制器,无法直接访问Router;
  • 通过JS文件动态加载edit.fragment.xml和readonly.fragment.xml实现编辑/只读模式切换,手动绑定父容器上下文。

核心需求

保存后无需重载页面,即可刷新视图或当前绑定上下文。

具体问题

  1. 是否可通过编程方式无需location.reload()刷新上下文或视图?
  2. 此类扩展场景有哪些模式或最佳实践?

额外发现

首次加载Product条目时,Network中的OData V4请求包含Product?$extend=...及general_info所有字段;但保存后返回ListReport点击其他Product时,请求中的Product?$extend=...缺少更新的两个字段,推测数据被缓存,Fiori Elements未重新请求。


解决方案

1. 无需location.reload()的刷新方案

针对OData V4模型的缓存不一致问题,可通过以下几种编程方式实现刷新:

方式一:强制刷新特定绑定上下文

在submitBatch完成后,对当前操作的上下文调用refresh方法并传入true参数(跳过缓存,强制从服务器拉取):

await oModel.submitBatch("auto");
// 刷新当前Product主上下文
oCtx.refresh(true);
// 刷新general_info关联上下文
oGenCtx.refresh(true);

方式二:清除实体集缓存并触发绑定更新

如果上下文刷新无效,可直接清除对应实体集的缓存,再刷新父容器绑定:

await oModel.submitBatch("auto");
// 清除Products和GeneralInfo实体集的缓存
oModel.clearCache("/Products");
oModel.clearCache("/GeneralInfo");
// 刷新父容器绑定,同步视图数据
oVBox.getBindingContext().refresh(true);

方式三:利用OData V4的自动刷新配置

在绑定上下文或列表绑定时添加$$refreshAfterChange: true,让模型在提交批量操作后自动刷新相关数据:

// 修改general_info的绑定配置
const oBinding = oModel.bindContext(sPath, null, {
  $$updateGroupId: "auto",
  $$refreshAfterChange: true // 提交后自动刷新该上下文
});
// 创建GeneralInfo时的列表绑定也添加该配置
const oListBinding = oModel.bindList("/GeneralInfo", null, [], [], {
  $$updateGroupId: "auto",
  $$refreshAfterChange: true
});

2. 片段扩展场景的模式与最佳实践

模式一:复用Fiori Elements内置API

即使使用片段扩展,也可通过模型获取根组件,进而调用Fiori Elements的ExtensionAPI实现视图刷新:

const oComponent = oModel.getOwnerComponent();
const oExtensionAPI = oComponent.getExtensionAPI();
// 刷新当前页面所有绑定
oExtensionAPI.refresh();
// 或仅刷新指定实体集
oExtensionAPI.refresh("/Products");

模式二:统一上下文传递

避免通过getParent().getParent()硬编码获取容器,在动态加载片段时直接传入父上下文:

this.loadFragment({
  name: "your.namespace.edit.fragment",
  bindingContext: oParentCtx // 父容器的上下文
}).then(oFragment => {
  oVBox.addItem(oFragment);
});

模式三:更新组与自动刷新配合使用

将OData V4的$$updateGroupId与$$refreshAfterChange配置配合,确保批量提交后模型自动同步服务器数据,减少缓存不一致问题。

模式四:优化控件层级获取方式

给父容器设置唯一id,通过this.byId("containerId")获取容器,替代硬编码的getParent()链式调用,提升代码可维护性。


内容的提问来源于stack exchange,提问作者Aleksandar Grujic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 02:12:29