Hybris切换视角首次加载自定义backoffice widget无数据问题咨询
问题根因分析
- 数据加载逻辑写在
preInitialize方法中,该方法仅在widget首次实例化时执行一次,后续从视角树切换进入时不会重新触发 - ZUL页面中直接在head内声明
const orders = [${widgetModel.orders}][0];,首次加载时widgetModel还未完成数据赋值,导致前端拿到的orders为undefined,刷新页面后widget提前完成初始化所以数据正常 - Backoffice默认会复用widget实例,不会每次切换视角都重新初始化组件
解决方案
步骤1:修改Controller初始化逻辑
将数据加载逻辑迁移到onWidgetInstanceOpen方法中,该方法每次打开widget(即点击视角树条目进入)时都会被触发:
package org.training.widgets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.hybris.cockpitng.core.model.WidgetModel; import org.training.services.customGraphService; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.select.annotation.WireVariable; import org.zkoss.zk.ui.util.Clients; import com.hybris.cockpitng.util.DefaultWidgetController; import java.util.List; public class customGraphController extends DefaultWidgetController { private static final long serialVersionUID = 7954736389190109887L; @WireVariable private transient customGraphService customGraphService; // 移除preInitialize中的数据加载逻辑,改为每次打开widget时执行 @Override public void onWidgetInstanceOpen() { super.onWidgetInstanceOpen(); String ordersJson = convertAllOrderModelsToJSON(); // 直接调用前端初始化方法,保证数据实时性 Clients.evalJavaScript("initCharts(" + ordersJson + ")"); } private String convertAllOrderModelsToJSON() { List list = customGraphService.getAllOrdersModels(); Gson gson = new GsonBuilder().setPrettyPrinting().create(); return gson.toJson(list); } }
步骤2:修改ZUL和前端JS逻辑
调整ZUL中脚本的执行逻辑,将图表初始化封装为可调用的方法:
- 移除ZUL head中直接声明
const orders的代码 - 修改
graphConfiguration.js,将原有的初始化逻辑封装为全局方法initCharts:
// 原有的图表初始化逻辑封装为方法 function initCharts(orders) { // 原有绘制lineChart1、pieChart1、barChart1的逻辑放在这里,直接使用传入的orders参数 }
修改后的ZUL页面:
<?xml version="1.0" encoding="UTF-8"?> <widget xmlns="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:w="http://www.zkoss.org/2005/zk/client" xmlns:zk="http://www.zkoss.org/2005/zk" xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.hybris.com/schema/cockpitng/zul/zul.xsd" height="100%"> <html> <h:head> <h:script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js" integrity="sha512-CWVDkca3f3uAWgDNVzW+W4XJbiC3CH84P2aWZXj+DqI6PNbTzXbl1dIzEHeNJpYSn4B6U8miSZb/hCws7FnUZA==" crossorigin="anonymous" referrerpolicy="no-referrer" defer="true"/> <h:script defer="true" src="widgetClasspathResource/widgets/customGraphWidget/graphConfiguration.js?v=1"/> </h:head> <h:body> <h:div style="height: 100%; width: 80%; margin: auto; overflow: hidden;"> <h:div style="background-color: white;height:35%;margin: 40px auto auto ;padding:20px;border: 2px solid #d7dee5"> <h:canvas id="lineChart1"></h:canvas> </h:div> <h:div style="background-color: white;width: 30%;height:35%;margin: 30px auto auto 0px ;padding:20px;border: 2px solid #d7dee5;float: left"> <h:canvas id="pieChart1"></h:canvas> </h:div> <h:div style="background-color: white;width: 60%;height:35%;margin: 30px 0px auto auto ;padding:20px;border: 2px solid #d7dee5"> <h:canvas id="barChart1"></h:canvas> </h:div> </h:div> </h:body> </html> </widget>
步骤3(可选):配置widget每次打开都重新创建实例
如果需要彻底避免widget实例复用带来的缓存问题,可以在widgetdefinition.xml中添加实例模式配置:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!-- Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved --> <widget-definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.hybris.com/schema/cockpitng/widget-definition.xsd" id="org.training.widgets.customGraphWidget"> <name>customGraph Sample Widget</name> <description>customGraph Sample Widget</description> <defaultTitle>customGraph Sample Widget</defaultTitle> <author>DucVan</author> <version>1.0</version> <view src="customGraphWidget.zul" /> <keywords> <keyword>graphbackoffice</keyword> </keywords> <controller class="org.training.widgets.customGraphController" /> <!-- 添加以下配置 --> <settings> <setting key="instance.mode" value="always-create" /> </settings> </widget-definition>
该配置会让每次点击视角树条目进入时,都创建一个全新的widget实例,完全重新初始化所有逻辑。
内容的提问来源于stack exchange,提问作者codesenpai_
相关产品推荐
相关产品推荐

