1

I have a Primefaces DataTable based on LazyDataModel. I successfully managed to load data in the table but I am not being able to use setPropertyActionListener to show the selected items in a Dialog nor to edit rows. I am using request scope and I noticed this issue seems to be solved in session scope, but I would rather use the former (View scope won't even load data in the table). I already tried to override getRowData and getRowKey methods but they don't even get called. I have none of this issues when I don't use the lazy model approach.

Could this be a injection related issue that I am missing or LazyDataModel won't work outside session scope?

public class LazyDataModelBase<T> extends LazyDataModel<T> {

private volatile AbstractFacade<T> facade;

public LazyDataModelBase(AbstractFacade<T> facade) {
    super();
    this.facade = facade;
}

public final AbstractFacade<T> getFacade() {
    return facade;
}

public final void setFacade(AbstractFacade<T> facade) {
    this.facade = facade;
}

@Override
public List<T> load(int first, int pageSize, String sortField,
        SortOrder sortOrder, Map<String, String> filters) {
    List<T> list = facade.load(first, pageSize,
            sortField, sortOrder, filters);
    if (list == null) {
        throw new RuntimeException("Problem.");
    }
    // I am using the following line for debugging:
    // throw new RuntimeException(list.toString());
    setRowCount(facade.count());
    return list;
}

}

UserLazyDataModel looks like this

public class UserLazyDataModel extends LazyDataModelBase<User> {

    private UserFacade facade;

    public UserLazyDataModel(UserFacade facade) {
        super(facade);
    }

    public List<User> getRowData(String rowKey) {
        return facade.findById(Integer.parseInt(rowKey)); // findById as defined in UserFacade
    }

    ...

My backing bean looks like this

@Named(value = "userController")
@RequestScoped
public class UserController implements Serializable {

    private User current;
    @EJB
private UserFacade ejbFacade;
private LazyDataModelBase<User> items;
private Integer itemId;
private int pageSize = 10;

public UserController() {
    items = new UserLazyDataModel(ejbFacade);
}

public UserFacade getUserFacade() {
    return ejbFacade;
}

public void setUserFacade(UserFacade facade) {
    this.ejbFacade = facade;
    //items.setFacade(facade);
}

public User getSelected() {
    if (current == null) {
        this.current = new User();
    }
    return current;
}

public void setSelected(User selected) {
    this.current = selected;
}

public void setSelected(Integer id) {
    this.itemId = id;
    current = ejbFacade.find(id);
}

public Integer getItemId() {
    return itemId;
}

public void setItemId(Integer id) {
    this.itemId = id;
    current = ejbFacade.findById(id);
}

public int getPageSize() {
    return pageSize;
}

public void setPageSize(int pageSize) {
    this.pageSize = pageSize;
}

private void setDefaultStatus() {
    current.setStatusId(ejbFacade.getDefaultStatus());
}

public String create() {
    current.setDateCreated(new Date());
    if (current.getStatusId() == null) {
        setDefaultStatus();
    }
    current.hashPassword();

    try {
        ejbFacade.create(current);
        JsfUtil.addSuccessMessage("User guardado exitosamente");
        return "success-create";
    } catch (Exception e) {
        JsfUtil.addErrorMessage(e, "A persistence error ocurred.");
        return null;
    }
}

public String prepareList() {
    //current = null;
    return "index?faces-redirect=true";
}

public String prepareCreate() {
    return "create?faces-redirect=true";
}

public String prepareEdit() {
    return "edit";
}

public void onRowSelect() {
    current = ejbFacade.findById(itemId);
}

public void update() {
    try {
        ejbFacade.edit(current);
        JsfUtil.addSuccessMessage("User guardado exitosamente");
    } catch (Exception e) {
        JsfUtil.addErrorMessage(e, "A persistence error ocurred.");
    }
}

public void delete() {
    try {
        ejbFacade.remove(current);
        current = null;
        JsfUtil.addSuccessMessage("role deleted");
    } catch (Exception e) {
        JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
    }
}

public LazyDataModelBase<User> getItems() {
    items.setFacade(ejbFacade);
    items.setPageSize(pageSize);
    return items;
}

public void setItems(LazyDataModelBase<User> model) {
    this.items = model;
}

}

And this is my view

    <h:form prependId="false">
        <p:commandButton immediate="true" style="margin: 10px 0;" value="Nuevo" icon="ui-icon-plus" action="#{userController.prepareCreate}" ajax="false" />
    </h:form>
    <h:form id="listForm">
        <br />
        <p:growl id="messages" showDetail="true"/>
        <p:dataTable var="item" value="#{userController.items}" rows="#{userController.pageSize}"
                     lazy="true" selectionMode="single" rowKey="#{item.userId}" selection="#{userController.selected}"
                     paginator="true" id="itemsTable"  rowsPerPageTemplate="10,30,50">


            <p:ajax event="rowSelect" listener="#{userController.onRowSelect}" update=":listForm:itemDisplay" oncomplete="itemDialog.show()" />

            <p:column headerText="ID" id="userId" sortBy="#{item.userId}" style="width: 10px;">
                #{item.userId}
            </p:column>

            <p:column headerText="First Name" id="first-name" sortBy="#{item.firstName}">
                #{item.firstName}
            </p:column>

            <p:column headerText="Last Name" id="last-name" sortBy="#{item.lastName}">
                #{item.lastName}
            </p:column>

            <p:column headerText="Email" id="email" sortBy="#{item.email}" filterBy="#{item.email}">
                #{item.email}
            </p:column>

            <p:column headerText="User" id="name" sortBy="#{item.username}">
                #{item.username}
            </p:column>

            <p:column headerText="birthdate" id="birthdate" sortBy="#{item.birthdate}">
                <h:outputText value="#{item.birthdate}" >
                    <f:convertDateTime type="date" pattern="yyyy/MM/dd"/>
                </h:outputText>
            </p:column>

            <p:column headerText="role" id="status" sortBy="#{item.statusId.name}">
                #{item.statusId.name}
            </p:column>



            <p:column style="width:32px;">
                <h:panelGrid columns="3" class="datarow-icons">
                    <p:commandButton icon="ui-icon-trash" update=":listForm:itemsTable :listForm:confirmDelete"
                                     oncomplete="deleteDialog.show()">
                        <f:setPropertyActionListener value="#{item}" target="#{userController.selected}" />
                    </p:commandButton>

                    <p:commandButton icon="ui-icon-pencil" immediate="true" action="#{userController.prepareEdit}" ajax="false">
                        <f:setPropertyActionListener value="#{item}" target="#{userController.selected}" />
                    </p:commandButton>

                    <p:commandButton id="select-button" 
                                     update=":listForm:itemDisplay" 
                                     oncomplete="itemDialog.show()" icon="ui-icon-search"
                                     title="view" >
                        <f:setPropertyActionListener value="#{item}" target="#{userController.selected}" />
                    </p:commandButton>
                </h:panelGrid>
            </p:column>
        </p:dataTable>
        <p:dialog widgetVar="itemDialog" resizable="false"
                  showEffect="explode" hideEffect="explode" header="Item Detail">
            <p:panelGrid columns="2" id="itemDisplay" style="width: 250px;">
                <h:outputText value="ID: " />
                <h:outputText value="#{userController.selected.userId}" />

                <h:outputText value="Name: " />
                <h:outputText value="#{userController.selected.username}" />

                <h:outputText value="Description: " />
                <h:outputText value="#{userController.selected.firstName}" />
            </p:panelGrid>
        </p:dialog>
        <p:confirmDialog id="confirmDelete" header="Confirm delete" 
                         widgetVar="deleteDialog" severity="alert"
                         showEffect="fade" hideEffect="fade"
                         closable="false"
                         message="¿Realmente desea borrar '#{userController.selected.toString()}' ?">
            <p:commandButton id="decline" value="Not Yet" 
                             onclick="deleteDialog.hide();" type="button" />
            <p:commandButton id="accept" value="Confirmar" 
                             update=":listForm" 
                             oncomplete="deleteDialog.hide();"
                             action="#{userController.delete}" ajax="false">
            </p:commandButton>
        </p:confirmDialog>
    </h:form>
4

1 回答 1

0

我设法通过在我的 UserLazyDataModel (我展示的 LazyDataModelBase 的子类)中覆盖 getRowData 来让 rowSelect 工作,如下所示:

@Override
public User getRowData(String rowKey) {
    try {
        return ((UserFacade) getFacade()).findById(Integer.parseInt(rowKey));
    } catch (Exception e) {
        return null;
    }

}

并删除

rowkey="#{item.userId}"

dataTable 声明中的属性。我在子类 UserLazyDataModel 中声明了一个外观,默认情况下这与父类 LazyDataModelBase 不同(设置为 null)。解决方案是从子类中删除该字段并通​​过 getFacade 方法访问父字段,最后将其强制转换为 UserFacade。

setPropertyActionListener 还没有工作。

于 2013-07-18T21:41:38.150 回答