调用PlanningCalendar.setFirstDayOfWeek后事件重复触发问题咨询
调用sap.m.PlanningCalendar的setFirstDayOfWeek后事件重复触发的问题
问题现象
调用PlanningCalendar.setFirstDayOfWeek()方法后,onSelectAppointment等所有日历事件会被重复触发:
- 调用1次方法,事件触发2次;调用2次方法,事件触发3次,触发次数随调用次数递增
- 官方示例中无法复现,但在本地项目通过异步函数的
then()回调调用该方法时会出现此问题 - 本地项目使用全局
ContextUtils存储控制器上下文,而官方示例直接在控制器内定义上下文
可能原因
- 控件内部事件重复订阅:
setFirstDayOfWeek会触发PlanningCalendar的视图重建或配置更新,若UI5内部在更新时未正确清理旧的事件监听,会导致新监听被重复添加,最终事件触发多次。 - 全局上下文导致的实例污染:
ContextUtils使用全局变量存储控制器上下文,若控制器销毁时未清理该变量,或存在重复初始化情况,可能导致事件处理函数被多次关联到同一个控件实例。 - 异步时机的渲染冲突:在异步回调中调用配置修改方法时,PlanningCalendar可能已完成初始化渲染,再次修改触发的重新渲染会与初始渲染的事件注册逻辑产生冲突,导致重复绑定。
解决方案
1. 使用模型绑定替代直接调用方法
通过数据绑定设置firstDayOfWeek属性,让UI5自动处理属性变更,避免手动调用方法触发的内部重复逻辑:
<!-- XML视图中给PlanningCalendar添加属性绑定 --> <PlanningCalendar id="PC1" firstDayOfWeek="{config>/firstDay}" ... />
// 控制器onInit中初始化配置模型 onInit: function () { // ... 其他初始化代码 ... var oConfigModel = new JSONModel({ firstDay: 0 // 默认值 }); this.getView().setModel(oConfigModel, "config"); simpleFunc().then(() => { // 仅更新模型,UI5会自动同步到控件 oConfigModel.setProperty("/firstDay", 0); }); // ... 其他代码 ... }
2. 限制setFirstDayOfWeek的调用次数
确保该方法仅被调用一次,避免重复触发控件更新:
// 在控制器内添加标记,防止重复调用 onInit: function () { // ... 其他初始化代码 ... let hasSetFirstDay = false; simpleFunc().then(() => { if (!hasSetFirstDay) { this.byId("PC1").setFirstDayOfWeek(0); hasSetFirstDay = true; } }); // ... 其他代码 ... }
3. 修复全局ContextUtils的生命周期管理
确保控制器上下文仅在当前实例有效,销毁时清理全局变量:
// 控制器中 onInit: function () { ContextUtils.set(this); }, onExit: function () { ContextUtils.set(null); // 控制器销毁时清理上下文 }
4. 手动清理事件监听(不推荐XML绑定场景)
若事件是通过代码动态绑定的,可在调用setFirstDayOfWeek前先解绑,再重新绑定:
function setFirstDay() { let pc = ContextUtils.get().byId("PC1"); // 先解绑原有监听 pc.detachSelectAppointment(ContextUtils.get().onSelectAppointment); pc.setFirstDayOfWeek(0); // 重新绑定监听 pc.attachSelectAppointment(ContextUtils.get().onSelectAppointment, ContextUtils.get()); }
5. 升级UI5版本
若使用的UI5版本存在已知bug,尝试升级到最新稳定版本(如1.120+),官方可能已修复此类事件重复触发的问题。
内容的提问来源于stack exchange,提问作者malkoto1
相关产品推荐
相关产品推荐

