【问题标题】:How to extend AjaxBehaviorEvent dispatched from @FacesComponent?如何扩展从@FacesComponent 调度的 AjaxBehaviorEvent?
【发布时间】:2015-01-12 22:16:27
【问题描述】:

当我使用 <cc:clientBehavior name="chartUpdated" event="change" targets="chartdata"/>复合组件 调度 ajax 事件时,我使用 <f:ajax event="chartUpdated" listener="#{bean.updateListener}">Facelet 页面 中捕获它.在 backing bean 中,我捕获了 AjaxBehaviorEvent 类型的事件。

public void updateListener(AjaxBehaviorEvent event){
      ...
}

我知道我可以扩展 AjaxBehaviorEvent 并在其中传递已更改的对象。 For example, Primefaces's Scheduler uses this approach:

  <p:ajax event="eventMove" listener="#{scheduleView.onEventMove}" update="messages" />

和支持bean:

 public void onEventMove(ScheduleEntryMoveEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event moved", "Day delta:" + event.getDayDelta() + ", Minute delta:" + event.getMinuteDelta());

        addMessage(message);
    }

使用 复合组件@FacesComponent 是否可以实现相同的功能?

提前谢谢你!

【问题讨论】:

    标签: jsf jsf-2 composite-component


    【解决方案1】:

    很高兴再次见到你:)

    继续您之前的@​​987654321@:

    覆盖 queueEvent() 以过滤有趣的事件(来自特定组件的更改)并将它们的队列推迟到验证阶段,以便能够获取转换和验证的值:

    @FacesComponent("rangeComponent")
    public class RangeComponent extends UIInput implements NamingContainer
    {
        private final List<AjaxBehaviorEvent> customEvents = new ArrayList<>();
        ...
    
        @Override
        public void queueEvent(FacesEvent event)
        {
            FacesContext context = getFacesContext();
            if(event instanceof AjaxBehaviorEvent)
            {
                Map<String, String> params = context.getExternalContext().getRequestParameterMap();
                String eventName = params.get("javax.faces.behavior.event");
                Object eventSource = event.getSource();
    
                if("change".equals(eventName) && (from.equals(eventSource) || to.equals(eventSource)))
                {
                    customEvents.add((AjaxBehaviorEvent) event);
                    return;
                }
            }
    
            super.queueEvent(event);
        }
    
        @Override
        public void validate(FacesContext context)
        {
            super.validate(context);
    
            if(from.isValid() && to.isValid())
            {
                for(AjaxBehaviorEvent event : customEvents)
                {
                    SelectEvent selectEvent = new SelectEvent(this, event.getBehavior(), this.getValue());
    
                    if(event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES))
                    {
                        selectEvent.setPhaseId(PhaseId.PROCESS_VALIDATIONS);
                    }
                    else
                    {
                        selectEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
                    }
    
                    super.queueEvent(selectEvent);
                }
            }
        }
    
        ...
    }
    

    然后将特定的事件监听器添加到您的托管 bean:

    @ManagedBean
    @ViewScoped
    public class RangeBean implements Serializable
    {
        private static final long serialVersionUID = 1L;
    
        private String range = "01/01/2015-31/12/2015";
    
        public void onSelect(SelectEvent event)
        {
            Messages.addGlobalInfo("[{0}] selected: [{1}]", event.getComponent().getId(), event.getObject());
        }
    
        public String getRange()
        {
            return range;
        }
    
        public void setRange(String range)
        {
            this.range = range;
        }
    }
    

    【讨论】:

    • 我也是 :) 谢谢你的帮助。我在没有实现 validate 方法的情况下实现了您的解决方案,并且工作正常。我错过了什么?
    • 取决于相位。如果事件在APPLY_REQUEST_VALUES 阶段触发(如“更改”事件),则对component.getValue() 的调用将返回一个过时的值。否则不需要推迟,即在PROCESS_VALIDATIONS阶段触发“valueChange”事件。
    • 请注意,由于Constants,此方法与 PrimeFaces 紧密耦合。如果您希望该组件可在所有组件库中重复使用,则最好删除 PrimeFaces 特定的导入。
    • @MicheleMariotti,有几个截止日期在工作,我现在终于可以实施您的解决方案了。我有一个问题,你为什么使用 array customEvents?以及应该如何以及何时清理?如果在致电Validate 之后,我们还需要array 吗?可以同时处理几个事件吗?
    • customEvents 是不同方法调用(可能还有不同的生命周期阶段)之间的临时存储。由于组件是请求范围的,因此无需清理它,但是,是的,它可以在 validate() 的末尾进行清理,因为它不再在同一个请求中使用。是的,可以以串行方式同时处理几个事件。
    猜你喜欢
    • 2010-10-30
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 2011-12-29
    • 2012-06-30
    相关资源
    最近更新 更多