我有一个问题调试了半天。我还是想不通。基本上,我使用数据表可扩展功能为每一行显示一些额外的选项。用户可以检查其中一些或不检查,然后用户单击更新按钮来更新数据库。所以一排会有很多选择。
<f:selectItems value="#{adminBean.allTabNames}" />
是使用收集用户选择的选项,然后一旦用户单击更新,托管bean将它们保存到数据库中。
然后问题是public void setSelectedTabsNames(List<String> selectedTabsNames) {
this.selectedTabsNames = selectedTabsNames;
}
使用预期值或空值(空列表)多次调用该方法。这些值是随机传递的,有时没有值。
看法:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:form id="form1">
<p:growl id="growl" showDetail="true"/>
<p:dataTable var="user" value="#{adminBean.users}" scrollable="false"
>
<p:ajax event="rowToggle" listener="#{adminBean.onRowToggle(user.id)}" update=":form:tabView:form1:growl" />
<f:facet name="header">
All Users
</f:facet>
<p:column style="width:2%">
<p:rowToggler />
</p:column>
<p:column headerText="First Name">
<h:outputText value="#{user.firstname}" />
</p:column>
<p:column headerText="Last Name">
<h:outputText value="#{user.lastname}" />
</p:column>
<p:column headerText="Password">
<h:outputText value="#{user.password}" />
</p:column>
<p:column headerText="Active">
<h:outputText value="#{user.active}" />
</p:column>
<p:column headerText="Last Login">
<h:outputText value="#{user.timestamp}" />
</p:column>
<p:column headerText="Notes">
<h:outputText value="#{user.notes}" />
</p:column>
<p:rowExpansion>
<h:panelGrid id="display" columns="1" cellpadding="4">
<h:outputText value="Tabs: " />
<p:selectManyCheckbox id="grid" value="#{adminBean.selectedTabsNames}"
layout="pageDirection" >
**<f:selectItems value="#{adminBean.allTabNames}" />**
</p:selectManyCheckbox>
</h:panelGrid>
<br/>
<p:commandButton value="Update" id="submit" actionListener="#{adminBean.updateTabsForUser(user.id)}" ajax="true" />
</p:rowExpansion>
</p:dataTable>
</h:form>
托管豆:
setSelectedTabsNames(列出选定的TabsNames)
package org.userlogin.view;
import java.io.Serializable;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import org.userlogin.db.entity.FopsUser;
import org.userlogin.service.UserService;
@ManagedBean
@ViewScoped
public class AdminBean implements Serializable {
private static final long serialVersionUID = -9002632063713324598L;
private List<FopsUser> users;
private List<String> selectedTabsNames;
private List<String> allTabNames;
private UserService us;
public AdminBean() {
us = new UserService();
users = us.getAllUsers();
allTabNames = us.getAllTabs();
}
public List<FopsUser> getUsers() {
return users;
}
public void setUsers(List<FopsUser> users) {
this.users = users;
}
public void setSelectedTabsNames(List<String> selectedTabsNames) {
this.selectedTabsNames = selectedTabsNames;
}
public List<String> getSelectedTabsNames() {
return selectedTabsNames;
}
public List<String> getAllTabNames() {
return allTabNames;
}
public void setAllTabNames(List<String> allTabNames) {
this.allTabNames = allTabNames;
}
public void updateTabsForUser(Long uid) {
us.updateTabsUser(selectedTabsNames);
}
public void onRowToggle(Long uid) {
//set current selected user
us.setCurrent(uid);
this.selectedTabsNames = us.getTabNamesByUserId(uid);
}
}
- - - - - - - -更新 - - - -
删除嵌套的“表单”,但仍然无法正常工作。我发现问题不影响数据表的最后一行。假设我在数据表中有三行,当我操作前两行时,设置器被多次调用并在最后一次设置为 null。但是对于最后一行,setter 仍然被多次调用。最后一次调用设置期望值。现在我只是添加
public void setSelectedOptions(List<String> selectedOptions) {
if (selectedOptions == null || selectedOptions.size() == 0) {
return;
}
this.selectedOptions = selectedOptions;
}
还是很丑...
- - - - - - 更新 - - - - -
<p:selectManyCheckbox id="grid" value="#{user.selectedTabsNames}"
layout="pageDirection" >
**<f:selectItems value="#{adminBean.allTabNames}" />**
</p:selectManyCheckbox>
应该这样设计:将 selectedTabsNames 放入 User 对象中。但仍然无法正常工作。因为我有这个 ajax 提交按钮,所以这请求每个 selectedTabsNames 都被调用并传入空列表。
<p:rowExpansion>
<h:panelGrid id="display" columns="1" cellpadding="4">
<h:outputText value="Tabs: " />
<p:selectManyCheckbox id="grid" value="# {user.selectedTabsNames}"
layout="pageDirection" >
<f:selectItems value="#{adminBean.allTabNames}" />
</p:selectManyCheckbox>
<p:commandButton value="Update" id="submit" ajax="true" />
</h:panelGrid>
<br/>
</p:rowExpansion>
----------------用我自己的解决方案更新(不是优雅的,但有效)-----
每次单击 ajax 按钮时,都会更新整个数据表。这意味着将使用预期值或空值调用每个 setSelectedItem 方法。我不知道如何改变它。
因此,我使用以下逻辑修改了从 ajax 按钮调用的 save() 方法:
public void save(Long userId, List<String> selectedItem) {
for (User user: users) {
if (user.getId() == userId) {
//update selectedItem in db for this user.
} else {
// read selectedItems in db
// update selectedItem in user object.
}
}
}