JSF仅在第二次请求时更新视图
关于如何解决这个问题,我已经没有什么想法了,事情就是这样:当我单击一个按钮(通过ajax)更新我的视图时,服务器端代码被正确执行,但是视图没有更新。当我发出第二个ajax请求时,它会用上一个ajax请求的值进行更新。我的页面中的每个ajax操作都会发生这种情况,这意味着视图中的所有内容都始终显示旧数据。多少岁?我请求老,永远 深入研究这个问题,我发现了一些可能的原因,在接下来的几行中,我将更详细地解释我想做什么 我有一个事件列表,每个事件发生在一个日期。我的页面显示12个日历,每个月一个,这些日历的目标是显示每月每天发生的事件。除了日历,我还有一个面板来更改年份和一个对话框。每次用户单击日历中的日期时,该对话框都会打开。通过对话,可以添加新事件、删除单击的事件并编辑单击的事件 每个日历都是我的自定义组件“日历”的一个实例,它总是接收一个月、一年和一个事件列表作为参数。事件列表通过我的managedBean中的方法“getEvents(int month)”传递 我的ajax调用是:JSF仅在第二次请求时更新视图,jsf,primefaces,Jsf,Primefaces,关于如何解决这个问题,我已经没有什么想法了,事情就是这样:当我单击一个按钮(通过ajax)更新我的视图时,服务器端代码被正确执行,但是视图没有更新。当我发出第二个ajax请求时,它会用上一个ajax请求的值进行更新。我的页面中的每个ajax操作都会发生这种情况,这意味着视图中的所有内容都始终显示旧数据。多少岁?我请求老,永远 深入研究这个问题,我发现了一些可能的原因,在接下来的几行中,我将更详细地解释我想做什么 我有一个事件列表,每个事件发生在一个日期。我的页面显示12个日历,每个月一个,这些日
- NextYear():在我的managedBean中以一年为增量,重新计算 事件。完成后,更新我的12个日历组件
- 上一年():类似于下一年
- updateEvent():更新或创建(如果不存在)单击的事件。 重新计算事件列表。完成后,在中更新日历 视图
- cancelEvent():取消事件,将其从事件列表中删除。 完成后更新视图
编辑:代码很复杂。为了简化问题,我将问题简化为“变更年”要求。如果我删除所有其他内容,问题仍然存在 我的看法是:
<h:outputStylesheet library="components" name="calendar/aqua/calendar.css" />
<link href="css/event_calendar.css" rel="stylesheet" type="text/css" />
<f:metadata>
<f:viewParam name="year" value="#{managementEventCalendar.year}" />
<f:event type="preRenderView" listener="#{managementEventCalendar.preRender()}" />
</f:metadata>
<script type="text/javascript">
<!-- update the url parameter "year" according to the managed bean -->
$(document).ready(function(){
updateUrlParameter('year', #{managementEventCalendar.year});
});
</script>
<p:growl autoUpdate="true" showDetail="true" life="#{initParam['primefaces.growl.life']}" widgetVar="growlWidgetVar" />
<!-- just a title, irrelevant -->
<comp:management_title image="imgs/title_image_eventcalendar.png" title="#{msg['title.eventcalendar']}" description="#{msg['description.eventcalendar']}" styleClass="event" />
<!-- form to change the year -->
<h:form>
<p class="text-center year-block">
<p:commandButton icon="ui-icon-circle-arrow-w" actionListener="#{managementEventCalendar.previousYear()}" update="@form :calendar" oncomplete="updateUrlParameter('year', #{managementEventCalendar.year - 1});" />
<h:outputText styleClass="year-title" value="#{managementEventCalendar.year}" />
<p:commandButton icon="ui-icon-circle-arrow-e" actionListener="#{managementEventCalendar.nextYear()}" update="@form :calendar" oncomplete="updateUrlParameter('year', #{managementEventCalendar.year + 1});" />
</p>
</h:form>
<!-- Grid of calendars (12, one for each month) -->
<h:panelGrid id="calendar" columns="3" width="100%" cellpadding="0" cellspacing="0" style="margin-bottom: 15px"
columnClasses="calendar-column left, calendar-column center, calendar-column right">
<comp:calendar month="0" year="#{managementEventCalendar.year}" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(0)}" />
<comp:calendar month="1" year="#{managementEventCalendar.year}" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(1)}" />
<comp:calendar month="2" year="#{managementEventCalendar.year}" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(2)}" />
<comp:calendar month="3" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(3)}" />
<comp:calendar month="4" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(4)}" />
<comp:calendar month="5" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(5)}" />
<comp:calendar month="6" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(6)}" />
<comp:calendar month="7" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(7)}" />
<comp:calendar month="8" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(8)}" />
<comp:calendar month="9" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(9)}" />
<comp:calendar month="10" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(10)}" />
<comp:calendar month="11" year="#{managementEventCalendar.year}" styleClass="espacamento_vertical" disablePast="false" theme="aqua"
type="edition" eventDates="#{managementEventCalendar.getEvents(11)}" />
</h:panelGrid>
$(文档).ready(函数(){
updateUrlParameter('year',{managementEventCalendar.year});
});
关于“日历”组件的一些解释:disablePast和theme是修饰性的。“类型=版本”表示日历单元格是可选择的。选择如何运作并不相关,因为我们只考虑我们想要改变年份的情况。我删除了所有关于活动选择、编辑和取消的代码。所有问题依然存在
请参见下面组件“日历”的代码
D
s
T
Q
Q
s
s
我的托管bean代码很简单,我在预呈现事件中分析url参数“year”,并在第一次调用getEvents(int month)时填充事件集合。事件集合实际上是一个月(0-11)与事件日期列表(EventDate)之间的映射。一个事件可以发生在多个日期(eventDate)中,每个eventDate都有一个日期和简短的描述。要转到上一年,我调用方法previousYear()。请参见下面的一些managedBean代码:
public void preRender(){
GregorianCalendar today = new GregorianCalendar();
if (year == 0) year = today.get(GregorianCalendar.YEAR);
}
@Override
public void updateEventCollection() {
eventMap = new HashMap<Integer, List<EventDate>>();
Iterator<Event> eventIterator = eventRepository.findNotCanceledByYear(year).iterator();
while (eventIterator.hasNext()){
Event e = eventIterator.next();
Iterator<EventDate> dateIterator = e.getEventDates().iterator();
while (dateIterator.hasNext()){
EventDate date = dateIterator.next();
GregorianCalendar day = new GregorianCalendar();
day.setTime(date.getDate());
int month = day.get(GregorianCalendar.MONTH);
List<EventDate> eventsInMonth = eventMap.get(month);
if (null == eventsInMonth){
eventsInMonth = new ArrayList<EventDate>();
}
eventsInMonth.add(date);
eventMap.put(month, eventsInMonth);
}
}
}
public List<EventDate> getEvents(int month){
if (null == eventMap) updateEventCollection();
List<EventDate> result = eventMap.get(month);
if (null == result) result = new ArrayList<EventDate>();
System.out.println("*** getting events of month " + month + ". " + result.size() + " dates were found.");
System.out.flush();
return result;
}
public void nextYear(){
year++;
updateEventCollection();
}
public void previousYear(){
year--;
updateEventCollection();
}
public void preRender(){
GregorianCalendar today=新Gre
public void preRender(){
GregorianCalendar today = new GregorianCalendar();
if (year == 0) year = today.get(GregorianCalendar.YEAR);
}
@Override
public void updateEventCollection() {
eventMap = new HashMap<Integer, List<EventDate>>();
Iterator<Event> eventIterator = eventRepository.findNotCanceledByYear(year).iterator();
while (eventIterator.hasNext()){
Event e = eventIterator.next();
Iterator<EventDate> dateIterator = e.getEventDates().iterator();
while (dateIterator.hasNext()){
EventDate date = dateIterator.next();
GregorianCalendar day = new GregorianCalendar();
day.setTime(date.getDate());
int month = day.get(GregorianCalendar.MONTH);
List<EventDate> eventsInMonth = eventMap.get(month);
if (null == eventsInMonth){
eventsInMonth = new ArrayList<EventDate>();
}
eventsInMonth.add(date);
eventMap.put(month, eventsInMonth);
}
}
}
public List<EventDate> getEvents(int month){
if (null == eventMap) updateEventCollection();
List<EventDate> result = eventMap.get(month);
if (null == result) result = new ArrayList<EventDate>();
System.out.println("*** getting events of month " + month + ". " + result.size() + " dates were found.");
System.out.flush();
return result;
}
public void nextYear(){
year++;
updateEventCollection();
}
public void previousYear(){
year--;
updateEventCollection();
}
<!-- Month days -->
<ui:repeat value="#{cc.calendar}" var="week">
<tr>
<ui:repeat value="#{week}" var="day">
<td class="#{(day.isToday() ? 'today' : '')} #{(empty (day.events)) ? '' : 'event'} #{(day.dayOfMonth eq 0) ? '' : 'selectable'}">
<h:panelGroup layout="block" styleClass="relative" rendered="#{not (day.dayOfMonth eq 0)}">
<h:outputText class="day-of-month" value="#{day.dayOfMonth}" />
</h:panelGroup>
</td>
</ui:repeat>
</tr>
</ui:repeat>
<h:outputText value="#{cc.attrs.year}" /><br />
<h:outputText value="#{cc.calendar.size()}" /><br />
<h:outputText value="#{cc.attrs.eventDates.size()}" /><br />