0

我有一个问题调试了半天。我还是想不通。基本上,我使用数据表可扩展功能为每一行显示一些额外的选项。用户可以检查其中一些或不检查,然后用户单击更新按钮来更新数据库。所以一排会有很多选择。

<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.
        }
    }

}
4

2 回答 2

1

当 ajax 事件被触发时,表单中的所有输入元素都会被发送。这意味着发送所有的 selectManyCheckbox(每行一个)。这就是为什么 setSelectedTabsNames 被多次调用的原因。

你必须改变你设计实现的方式。一种方法是将选定的选项存储在FopsUser对象中,因此您可以这样做value="#{user.selectedTabsNames}"

<p:selectManyCheckbox id="grid" value="#{user.selectedTabsNames}"
     layout="pageDirection" >
     **<f:selectItems value="#{adminBean.allTabNames}" />**
</p:selectManyCheckbox>

这样,每行的选定选项卡将单独存储。

于 2013-11-05T11:01:46.877 回答
0

我可能错了,但我不认为rowToggleevent 是可以处理行级参数的那种 ajax 事件。这样想:var="user"是一个行迭代级别的变量,可用于数据表中的每一行。rowToggle另一方面,事件是单级标签,作为一个组件适用于整个表格。因此,数据表可能没有可靠的方法来知道您在使用时指的是哪一行 adminBean.onRowToggle(user.id),它只会选择呈现的最后一行

获取切换行的详细信息的更有效方法是使用ToggleEvent支持 bean 中的侦听器,您不必传递变量:

     public void onRowToggle(ToggleEvent te){
        User theSelectedUser = (User)te.getData();
        int id = theSelectedUser.getId();
      }

在您看来,您现在将拥有:

<p:ajax event="rowToggle" listener="#{adminBean.onRowToggle}" update=":form:tabView:form1:growl"/>
于 2013-11-06T14:30:12.090 回答