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

如何在PrimeFaces p:schedule调用update()后重新应用自定义扩展器逻辑?

PrimeFaces <p:schedule> 自定义扩展器更新问题解决方案

问题1:确保动态生成的JavaScript重新渲染

核心原因

当前<h:panelGroup id="scriptPanel">未被纳入日程更新的PPR(部分页面渲染)范围,导致后台生成的JS代码无法同步更新到前端。

解决方案

  1. 明确触发scriptPanel的更新
    在所有触发日程数据更新的操作中,将scriptPanel加入更新目标。比如使用<p:commandButton>时:

    <p:commandButton value="刷新日程" 
                     action="#{appointmentsController.refreshAppointments}"
                     update="scriptPanel mySchedule" />
    

    如果是通过前端JS调用PF('mySchedule').update(),则需要手动发起AJAX请求更新scriptPanel:

    PF('mySchedule').update().done(function() {
        PrimeFaces.ajax.AjaxRequest(location.pathname, {
            formId: 'yourFormId', // 替换为你的表单ID
            update: 'scriptPanel',
            oncomplete: function() {
                applyScheduleCustomization(); // 更新后立即执行自定义逻辑
            }
        });
    });
    
  2. 优化后台JS生成逻辑
    将生成的JS封装为可重复调用的函数,避免全局代码重复执行导致的冲突:

    public String generateJsCustomization() {
        ScheduleConfig config = new ScheduleConfig(
            "", // dayCellContent
            "", // slotLaneContentDay
            "", // slotLaneContentWeek
            scheduleConfig.getBusinessHours() // businessHours
        );
    
        List<PatientAppointment> patientAppointments = appointments.stream()
                .flatMap(appointment -> appointment.getPatientAppointments().stream())
                .collect(Collectors.toList());
    
        StringBuilder jsBuilder = new StringBuilder();
        // 封装为可重复调用的函数
        jsBuilder.append("function applyScheduleCustomization() {");
        jsBuilder.append(JavaScriptGenerator.generateCustomizeSchedule(config, patientAppointments));
        jsBuilder.append("}");
        // 初始加载时立即执行
        jsBuilder.append("applyScheduleCustomization();");
    
        this.jsExtenderCode = jsBuilder.toString();
        return this.jsExtenderCode;
    }
    

问题2:调用update()后重新应用扩展器逻辑

核心原因

PF('mySchedule').update()仅同步服务器端的事件数据,不会重新初始化FullCalendar实例,因此自定义的eventContent逻辑不会自动生效。

解决方案

  1. 利用FullCalendar客户端API重新配置
    在update()的回调中,直接获取底层FullCalendar实例,重新设置eventContent选项并刷新事件:

    PF('mySchedule').update().done(function() {
        var calendar = PF('mySchedule').getCalendar(); // 获取FullCalendar实例
        // 重新设置eventContent逻辑
        calendar.setOption('eventContent', function(info) {
            // 替换为你的自定义内容生成逻辑
            return {
                html: '<div class="custom-event">' + info.event.title + 
                      '<span class="patient-info">' + info.event.extendedProps.patientName + '</span></div>'
            };
        });
        calendar.refetchEvents(); // 刷新事件以应用新配置
    });
    
  2. 复用封装好的自定义函数
    如果已经按问题1的方案封装了applyScheduleCustomization()函数,直接在回调中调用即可:

    PF('mySchedule').update().done(function() {
        applyScheduleCustomization();
    });
    
  3. 绑定FullCalendar渲染事件自动触发
    若希望每次日程渲染后都自动应用逻辑,可绑定eventAfterAllRendered事件(注意仅绑定一次,避免重复执行):

    // 页面加载时绑定一次
    $(document).ready(function() {
        var schedule = PF('mySchedule');
        var calendar = schedule.getCalendar();
        // 使用one()确保只绑定一次,或用off()先解绑再绑定
        calendar.one('eventAfterAllRendered', function() {
            applyScheduleCustomization();
        });
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:18:24