Прямое редактирование Primefaces DataTable - невозможно обновить модель без перезагрузки страницы - PullRequest
1 голос
/ 15 ноября 2011

Я пытаюсь реализовать таблицу с учетными записями пользователей, которая может быть изменена администраторами.Я использую компонент primefaces (2.2) DataTable с cellEditor.

У меня есть 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 с 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();
    }
}

Ответы [ 3 ]

4 голосов
/ 15 ноября 2011

Вы всегда возвращаете новый список, который является хорошо известной плохой практикой в ​​JSF, выбирая данные в геттере. Получатели могут вызываться несколько раз в течение жизненного цикла JSF. Кэшируйте свой список пользователей в переменной и лучше используйте область видимости.

Встроенное редактирование / обновление действительно работает, но вы теряете обновленную модель, возвращая каждый раз новый список.

1 голос
/ 16 ноября 2011

Проблема решена.Вокруг p: inputText = _ =

есть дополнительная h: форма
1 голос
/ 15 ноября 2011

Я не знаю, действительно ли я понял вашу проблему, но вы можете легко обновить свою таблицу или даже лучше обновить свою форму, но реализовав commandButton с атрибутом update:

Допустим, у вас есть форма с идентификатором myTableForm, тогда внутри этой формы у вас есть компонент dataTable и компонент commandButton. Эта кнопка будет выглядеть так:

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

Вы можете ссылаться на метод действия только в случае необходимости. В противном случае эта кнопка обновит всю вашу форму только путем выполнения запроса ajax. Ajax по умолчанию имеет значение true, но я добавил этот атрибут для него явно.

Конечно, у вас может быть другой логический дизайн ... вам не нужно реализовывать кнопку для этого, у вас могут быть некоторые слушатели ajax, некоторые функции javascript, которые будут запускаться при загрузке страницы, редактировать ячейки и т. Д. Я выбрал commandButton, потому что это самый простой способ понять логику ...

Пожалуйста, дайте мне знать, если это действительно то, что вы хотели.

...