Primefaces DataTable 内联编辑 - 如果不重新加载页面,则无法更新模型



我试图实现表与用户的帐户,这可以由管理员修改。我使用primefaces (2.2) DataTable组件与cellitor。

我有onRowEditListener,它使用manageUsers.onEditRow()方法通过UserDAO对象在数据库中持久化更改。

加载页面并更新表单元格后,数据库中的数据正确更改。不幸的是,当我试图再次更新前一行- (UserDAO)event.getObject();返回旧对象(第一次更改后的对象)和数据不更新。

当我重新加载页面(F5)和编辑行-然后数据被正确更改。

如何更新表或如何在不重新加载页面的情况下获得最新版本的用户?

使用Primefaces 2.2, JSF 2.1, Glassfish 3.1

页面:

                <p:column headerText="login" filterBy="#{u.user.login}" filterMatchMode="contains" style="width:150px">  
                    <p:cellEditor>  
                        <f:facet name="output">  
                            <h:outputText value="#{u.user.login}" />
                        </f:facet>  
                        <f:facet name="input">  
                            <h:form>
                                <p:inputText value="#{u.user.login}" />  
                            </h:form>
                        </f:facet>  
                    </p:cellEditor>  
                </p:column>  
                <p:column headerText="email" filterBy="#{u.user.email}" filterMatchMode="contains" style="width:150px">  
                    <p:cellEditor>  
                        <f:facet name="output">  
                            <h:outputText value="#{u.user.email}" />  
                        </f:facet>  
                        <f:facet name="input">  
                            <h:form>
                                <p:inputText  value="#{u.user.email}" />  
                            </h:form>
                        </f:facet>  
                    </p:cellEditor>  
                </p:column> 
                //... other fields

                <p:column headerText="Options">  
                    <p:rowEditor />  
                </p:column>  
            </p:dataTable>  
        </h:form>

ManageBean with ApplicationScope (CDI)

@Named
@ApplicationScoped
public class ManageUsers implements Serializable {
    @Inject
    /** Inject database */
    private DB db;
    /** List with all leaked data which is loaded from database */
    private List<UserDAO> users;
    private User selectedUser;
    private SelectItem[] manufacturerOptions;
    public ManageUsers() {
        manufacturerOptions = createFilterOptions();
    }
    public SelectItem[] getManufacturerOptions() {
        return manufacturerOptions;
    }
    public User getSelectedUser() {
        return selectedUser;
    }
    public void setSelectedUser(User selectedUser) {
        this.selectedUser = selectedUser;
    }
    /** List of users loaded from database */
    public void getDataFromDatabase() {
        try {
            users = db.getUserList();
            if (users == null) {
                throw new Exception("Pusta lista użytkowników");
            }
        } catch (Exception ex) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Nie można wyświetlić tabeli wyników",
                    "Nie udało się pobrać danych, prosimy spróbować ponownie później.");
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    }
    /**
     * Get list of leaked Data.
     * If list is null then getDataFromDatabase method is used.
     * @see DataExplorer.getDataFromDatabase()
     */
    public List<UserDAO> getUsers() {
        if (users == null) {
            getDataFromDatabase();
        }
        return users;
    }
    private SelectItem[] createFilterOptions() {
        SelectItem[] options = new SelectItem[3];
        options[0] = new SelectItem("", "-select-");
        options[1] = new SelectItem("true", "Admins");
        options[2] = new SelectItem("false", "Users");
        return options;
    }
    public void onEditRow(RowEditEvent event){ 
        UserDAO userDAO = (UserDAO)event.getObject();
        try {
            userDAO.update();
        } catch (UserDAOException ex) {
            Log.logger.error("User not edited,"+ex);
        }
        //getDataFromDatabase();
    }
}

您总是返回一个新列表,这是JSF中众所周知的坏做法,在getter中获取数据。在JSF生命周期中,getter可能被调用多次。在变量中缓存用户列表,最好使用视图作用域。

内联编辑/更新实际上是工作的,但你失去了更新的模型,每次返回一个新的列表。

我不知道我是否真的理解你的问题,但你可以很容易地更新你的表,甚至更好地更新你的表单,但实现一个commandButton与更新属性:

假设您有一个表单,它的id是myTableForm,然后在该表单中您有您的dataTable组件和commandButton组件。这个按钮看起来像这样:

<p:commandButton ajax='true' value='PersistData' update='myTableForm' action='if really needed' />

你只能在需要的时候引用一个动作方法。否则,这个按钮只会通过实现一个ajax请求来更新整个表单。Ajax默认为true,但我在那里显式地添加了该属性。

当然你可以有另一个逻辑设计…你不需要实现一个按钮来做到这一点,你可以有一些ajax监听器,一些javascript函数,将触发在页面加载,编辑单元格等…我选择了一个命令按钮,因为这是理解逻辑的最简单的方法…

请让我知道,如果这真的是你想要的。

问题解决。p:inputText =_=

周围有额外的h:form

最新更新