我尝试了不同的解决方案,但没有一个在我的情况下工作。我希望这个数据表中的所有行都是可选的。问题似乎是<ui:repeat
可能会覆盖对象......
我的豆子:
@ManagedBean
@ViewScoped
public class Chat {
private static Map<String, List<ChatObject>> chat = new LinkedHashMap<String, List<ChatObject>>();
private ChatObject selectedChatObject;
public void onChatRowSelection(){
if(getSelectedChatObject() != null){
System.out.println("test");
}
}
public List<Map.Entry<String, List<ChatObject>>> getChatList() {
Set<Map.Entry<String, List<ChatObject>>> productSet = chat.entrySet();
return new ArrayList<Map.Entry<String, List<ChatObject>>>(productSet);
}
@PostConstruct
public void postConstructMethod() {
if(chat.isEmpty()){
List<ChatObject> objectsList1 = new ArrayList<ChatObject>();
objectsList1.add(new ChatObject("3369818", "1", "1"));
objectsList1.add(new ChatObject("3369819", "2", "2"));
objectsList1.add(new ChatObject("3369820", "3", "3"));
chat.put("Chat Topic 1", objectsList1);
List<ChatObject> objectsList2 = new ArrayList<ChatObject>();
objectsList2.add(new ChatObject("3369813", "4", "4"));
objectsList2.add(new ChatObject("3369815", "5", "5"));
chat.put("Chat Topic 2", objectsList2);
}
}
public ChatObject getSelectedChatObject() {
return selectedChatObject;
}
public void setSelectedChatObject(ChatObject selectedChatObject) {
this.selectedChatObject = selectedChatObject;
}
}
我的JSF:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:form id="form" enctype="multipart/form-data" acceptcharset="ISO-8859-1">
<ui:repeat value="#{chat.chatList}" var="chatEntry">
<h2><h:outputText value="#{chatEntry.key}" /></h2>
<br />
<p:dataTable
value="#{chatEntry.value}"
var="chatEntryVar"
widgetVar="chatTableWV"
styleClass="geralBorderless"
style="cursor:pointer"
rowKey="#{chatEntryVar.id}"
rendered="true"
selectionMode="single"
selection="#{chat.selectedChatObject}"
paginatorAlwaysVisible="false">
<p:ajax event="rowSelect"
listener="#{chat.onChatRowSelection}"
oncomplete="chatTableWV.unselectAllRows();">
</p:ajax>
<p:column>
<h:outputText value="#{chatEntryVar.name}" />
</p:column>
</p:dataTable>
</ui:repeat>
</h:form>
</html>
我的地图中的所有5 ChatObject
都已成功显示在我的页面中。但是,当我点击与我添加到地图中的第二个列表相关的行时,onChatRowSelection
方法将仅打印“test”:objectList2
。 当我点击第一个列表中的行时,我添加了 objectList1
,当系统进入onChatRowSelection
方法时,selectedChatObject
将为空。我该如何解决这个问题?
答案 0 :(得分:3)
你的问题在这里:
<ui:repeat ...>
<p:dataTable ... widgetVar="chatTableWV">
<p:ajax ... oncomplete="chatTableWV.unselectAllRows();">
在JavaScript范围内为多个数据表分配了完全相同的widgetVar
名称。在效果中,生成以下JavaScript代码:
window['chatTableWV'] = new Widget(tableElement1);
window['chatTableWV'] = new Widget(tableElement2);
window['chatTableWV'] = new Widget(tableElement3);
// ...
基本上,每次迭代都会覆盖分配给声明的widgetVar
名称的最后一个对象,直到它最终引用最后一个。所有小部件对最后一个小部件的期望基本上都是不可用的,导致它们不再适用于行选择。
通过为每个人提供一个唯一的widgetVar
来相应地修复它。您可以使用<ui:repeat>
的迭代索引。
<ui:repeat ... varStatus="loop">
<p:dataTable ... widgetVar="chatTableWV_#{loop.index}">
<p:ajax ... oncomplete="chatTableWV_#{loop.index}.unselectAllRows();">
这样生成了以下JavaScript代码:
window['chatTableWV_0'] = new Widget(tableElement1);
window['chatTableWV_1'] = new Widget(tableElement2);
window['chatTableWV_2'] = new Widget(tableElement3);
// ...
最后,PrimeFaces小部件管理器可以找到它们。