JSF PrimeFaces Extensions Timeline:如何通过AJAX更新Timeline



我很难对时间轴进行基本的AJAX更新。

让我从一个基本的例子开始,我想根据下拉列表的选择更新时间轴的开始和结束时间:

<h:form id="form">
            <h:outputLabel for="period" value="#{str.schedule_period}"/>
            <h:selectOneMenu id="period" value="#{timelineController.period}" label="#{str.schedule_period}">
                <f:selectItems value="#{timelineController.periodWeeks}" />
                <p:ajax event="change" update="timeline" />
            </h:selectOneMenu>
            <pe:timeline id="timeline" value="#{timelineController.model}"
                         editable="true" 
                         eventMargin="0"
                         minHeight="120"
                         stackEvents="false"
                         start="#{timelineController.timelineStart}"
                         min="#{timelineControllertimelineStart}"
                         end="#{timelineController.timelineEnd}"
                         max="#{timelineController.timelineEnd}"
                         showNavigation="false" showButtonNew="false"
                         showCurrentTime="false"
                         axisOnTop="true"
                         timeZone="#{timelineController.timezone}"
                         zoomMin="28800000" 
                         dropActiveStyleClass="ui-state-highlight" dropHoverStyleClass="ui-state-hover">
                <p:ajax event="drop" listener="#{timelineController.onDrop}"
                        global="false" process="timeline"/>  
            </pe:timeline>
</h:form>

当我在下拉列表中选择一个项目时,会触发一个AJAX事件并在后台bean中设置period属性,但是新值不会反映在时间轴组件中。作为解决方案,我将时间轴包装在p:outputPanel中,并更新了包装器,它可以工作:

...
<h:selectOneMenu id="period" value="#{timelineController.period}" label="#{str.schedule_period}">
                <f:selectItems value="#{timelineController.periodWeeks}" />
                <p:ajax event="change" update="wrapper" />
</h:selectOneMenu>
...
<p:outputPanel id="wrapper">
   <pe:timeline id="timeline" value="#{timelineController.model}"
                         editable="true" 
                         eventMargin="0"
                         minHeight="120"
                         stackEvents="false"
                         start="#{timelineController.timelineStart}"
                         min="#{timelineControllertimelineStart}"
                         end="#{timelineController.timelineEnd}"
                         max="#{timelineController.timelineEnd}"
                         showNavigation="false" showButtonNew="false"
                         showCurrentTime="false"
                         axisOnTop="true"
                         timeZone="#{timelineController.timezone}"
                         zoomMin="28800000" 
                         dropActiveStyleClass="ui-state-highlight" dropHoverStyleClass="ui-state-hover">
                <p:ajax event="drop" listener="#{timelineController.onDrop}"
                        global="false" process="wrapper"/>  
            </pe:timeline>
</p:outputPanel>

注意,我还必须将p:ajax的process属性更改为wrapper。

所以我的第一个问题是:为什么不包装时间轴组件的更新工作?

我的第二个问题是关于拖放的。正如您可以从上面的代码中看到的那样,我为时间轴附加了一个drop侦听器。在我在下拉列表中进行选择之前,我还可以从p:dataList中拖放事件。一旦我在下拉列表中选择了一个新的时间段,时间轴就会得到适当的更新,但是我不能再将事件拖放到时间轴上了(onDrop侦听器不会被触发)。这是我的p:dataList:
<p:dataList id="eventsList" value="#{timelineController.users}"
                        var="user" itemType="none">  
                <h:panelGroup id="eventBox" layout="box" style="z-index:9999; cursor:move;">  
                    #{user.toString()}  
                </h:panelGroup>  
                <p:draggable for="eventBox" revert="true" helper="clone" cursor="move"/>  
</p:dataList> 

你知道这是怎么回事吗?

我还包括TimelineController类作为参考:

@ManagedBean
@ViewScoped
public class TimelineController {
    @EJB UserService userDao;
    private TimelineModel model;
    private String name;
    private ZoneId timezone;
    private Period period;
    private Duration defaultShiftDuration;
    private LocalDateTime timelineStart;
    private LocalDateTime timelineEnd;

    @PostConstruct
    protected void initialize() {
        timezone = ZoneId.of("Europe/Berlin);
        period = Period.ofWeeks(2);
        defaultShiftDuration = Duration.ofHours(8);
        timelineStart = LocalDateTime.now().with(DayOfWeek.MONDAY).withHour(0).withMinute(0).truncatedTo(ChronoUnit.MINUTES);
        // create timeline model
        model = new TimelineModel();
    }
    public TimelineModel getModel() {
        return model;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getTimezone() {
        return timezone.getId();
    }
    public void setTimezone(String timezone) {
        this.timezone = ZoneId.of(timezone);
    } 
    public List<SelectItem> getPeriodWeeks() {
        List<SelectItem> weeks = Lists.newArrayList();
        weeks.add(new SelectItem(1, "1 " + JsfUtil.getStringResource("schedule_week")));
        weeks.add(new SelectItem(2, "2 " + JsfUtil.getStringResource("schedule_weeks")));
        weeks.add(new SelectItem(3, "3 " + JsfUtil.getStringResource("schedule_weeks")));
        return weeks;
    }

    public int getPeriod() {
        return period.getDays() / 7;
    }
    public void setPeriod(int nWeeks) {
        this.period = Period.ofWeeks(nWeeks);
        timelineEnd = null;
    }
    public Date getTimelineStart() {
        return Date.from(timelineStart.atZone(timezone).toInstant());
    }
    public Date getTimelineEnd() {
        if (timelineEnd == null) {
            timelineEnd = timelineStart.plus(period);
        }
        return Date.from(timelineEnd.atZone(timezone).toInstant());
    }
    public void setStartsOn(String startsOn) {
        timelineStart = LocalDateTime.parse(startsOn + "T00:00");
        timelineEnd = null;
    }

    public List<User> getUsers(){
        return userDao.findAll();
    }
    public void onDrop(TimelineDragDropEvent e) {  
        // get dragged model object (event class) if draggable item is within a data iteration component,  
        // update event's start and end dates.  
        User user = (User) e.getData();  
        Date endDate =  Date.from(e.getStartDate().toInstant().plus(defaultShiftDuration));
        // create a timeline event (not editable)  
        TimelineEvent event = new TimelineEvent(user, e.getStartDate(), endDate, true, e.getGroup());  
        // add a new event  
        TimelineUpdater timelineUpdater = TimelineUpdater.getCurrentInstance(":form:timeline");  
        model.add(event, timelineUpdater);  
    }
 }

问题是时间轴组件中缺少widgetVar属性。对我来说,这看起来像是一个bug,因为我没有使用组件的客户端API。我将在PF Extensions项目中提交一个bug。

相关内容

  • 没有找到相关文章

最新更新