如何扩展从@FacesComponent调度的AjaxBehaviorEvent?

时间:2015-01-12 22:16:28

标签: jsf jsf-2 composite-component

当我使用<cc:clientBehavior name="chartUpdated" event="change" targets="chartdata"/>复合组件发送 ajax 事件时,我使用{在 Facelet页面中捕获它{1}}。在支持bean 中,我捕获了类型为 AjaxBehaviorEvent 的事件。

<f:ajax event="chartUpdated" listener="#{bean.updateListener}">

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

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

支持bean:

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

通过将复合组件 @FacesComponent 一起使用,是否可以实现相同的功能?

提前谢谢!

1 个答案:

答案 0 :(得分:2)

很高兴见到你,再次:)

继续之前的question

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

@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;
    }
}