【问题标题】:DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.启用选择时,DataModel 必须实现 org.primefaces.model.SelectableDataModel。
【发布时间】:2012-09-08 19:25:01
【问题描述】:

我正在尝试使用多行选择创建一个 DataTable,但我收到了一个错误,这是教程的链接http://www.primefaces.org/showcase/ui/datatableRowSelectionMultiple.jsf

这是我的 xhtml:

    <p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}" 
                     var="userObj"
                     selection="#  
         {projectAdminisrationMB.selectedUsers}"
 selectionMode="multiple" rowIndexVar="rowIndex"binding="#{table2}">
<p:column id="column3">
<f:facet name="header">
<h:outputText value=" user "></h:outputText>
</f:facet>

      <h:outputText value="#{userObj.name}"/>  

                            /
  <h:outputText value="#{userObj.lastName}"></h:outputText>

  &nbsp;
   <h:outputText value="#{userObj.firstName}"></h:outputText>
  </p:column>

    <f:facet name="footer">  
     <p:commandButton id="addProjectUser" value=" Add " onclick="dlg1.show()" />  
      <p:commandButton id="deleteProjectUser" value=" Delete " />  

    </f:facet> 

</p:dataTable>

托管 Bean:

 @ManagedBean
 @SessionScoped
 public class ProjectAdminisrationMB implements Serializable {

private static final long serialVersionUID = 1L;

private String projectName;
private List <User> projectUsersList;
private List<User> projectNoUsersList;
private List<User> selectedUsers;

private String projectAdmin;


public ProjectAdminisrationMB() {
    super();
    AdministrationProjectFinal administrationProjectFinal =new    
             AdministrationProjectFinal();
    this.projectUsersList=administrationProjectFinal.getUserList();
    this.projectNoUsersList=administrationProjectFinal.getNotUserList();
}



public String getProjectName() {
    return projectName;
}

public void setProjectName(String projectName) {
    this.projectName = projectName;
}



public List<User> getProjectUsersList() {
    return projectUsersList;
}



public void setProjectUsersList(List<User> projectUsersList) {
    this.projectUsersList = projectUsersList;
}



public String getProjectAdmin() {
    return projectAdmin;
}

public void setProjectAdmin(String projectAdmin) {
    this.projectAdmin = projectAdmin;
}

public List<User> getProjectNoUsersList() {
    return projectNoUsersList;
}



public void setProjectNoUsersList(List<User> projectNoUsersList) {
    this.projectNoUsersList = projectNoUsersList;
}



public List<User> getSelectedUsers() {
    return selectedUsers;
}



public void setSelectedUsers(List<User> selectedUsers) {
    this.selectedUsers = selectedUsers;
}




 }

我收到此错误:

  javax.faces.FacesException: DataModel must implement     
  org.primefaces.model.SelectableDataModel when selection is enabled.....

【问题讨论】:

标签: jsf primefaces facelets


【解决方案1】:

只需将此属性rowKey添加到数据表标签:

<p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}" 
 var="userObj"
 rowKey="#{userObj.name}"selection="#{projectAdminisrationMB.selectedUsers}"
 selectionMode="multiple" rowIndexVar="rowIndex"
 binding="#{table2}">

【讨论】:

  • rowKey 属性的值对于每一行必须是唯一的,并且在任何行中都不能为空。它可以是多个值的混合,例如:rowKey="#{userObj.id}-#{userObj.name}"
  • 由于我有一些带有过滤功能的列,我找到了一个解决方案,它还为属性 filteredValue 添加了一个值,将其指向相同类型对象的列表。
  • @Izerlotti 您的评论解决了我的问题。我想对下一个陌生人说清楚:当您过滤数据表并且在某个时刻重新呈现时(您更改选项卡或 smth),您的 bean 中需要有一个 List 的数据表项,您需要将其设置在表的 filteredValue 属性中。在其他地方你会得到DataModel must implement org.primefaces.model.SelectableDataModel 异常,这有点令人困惑。
【解决方案2】:

除了rowKey,您还可以将数据包装在真正实现org.primefaces.model.SelectableDataModel 的自定义模型中。如果

  • 你所有的类都有相同类型的@Id(例如long)并且可以实现相同的接口(例如EjbWithId
  • 您想为您的数据添加额外的功能,这些功能不是特定于域且不属于,例如User

界面可能是这样的:

public interface EjbWithId
{
  public long getId();
  public void setId(long id);
}

然后可以为所有类使用SelectableDataModel 的通用实现:

public class PrimefacesEjbIdDataModel <T extends EjbWithId>
       extends ListDataModel<T> implements SelectableDataModel<T>
{    
  public PrimefacesEjbIdDataModel(List<T> data)
  {  
    super(data);
  }  

  @Override public T getRowData(String rowKey)
  {  
    List<T> list = (List<T>) getWrappedData();  

    for(T ejb : list)
    {  
      if(ejb.getId()==(new Integer(rowKey))){return ejb;}  
    }
    return null;  
  }  

  @Override public Object getRowKey(T item) {return item.getId();}
}

在你的@ManagedBean:

private PrimefacesEjbIdDataModel<User> dmUser; //+getter
dmUser = new PrimefacesEjbIdDataModel<User>(administrationProjectFinal.getUserList());

【讨论】:

    【解决方案3】:

    如果您尝试将新项目添加到基础列表并忘记为该新项目的 rowKey 分配值,则会收到此错误。

    【讨论】:

    • 我遇到了这个确切的问题,创建了一个列表并向其中添加了一个对象,但我遇到了这个错误,你给那个新项目的 rowKey 赋值是什么意思?能给我举个例子吗? @Nublodeveloper
    • @user3672700 哇.. 2013 年,因为我写了答案。假设 rowKey 设置为表的字段...并且您向该表添加新行...并且忘记设置该字段的值。该行被加载/读入表时该字段的值不能为空。
    【解决方案4】:

    首先检查你是否添加了 rowKey="#{userObj.id}"

    那么您需要在 xhtml 中数据表的 filteredValue 属性中设置数据表 List,而不是 value

    【讨论】:

      猜你喜欢
      • 2012-05-17
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 2016-01-03
      • 1970-01-01
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多