p:dataTable排序在PrimeFaces 4.0中没有吸气剂

时间:2018-07-17 17:45:08

标签: primefaces

我有一个提供数据的数据表,但排序不起作用。

问题是,这些记录没有getFieldName getter,但是有getValue('FieldName')。这使我无需重新编译即可更改架构。

例如,一个这样的字段是日期。

我想要一些技巧来使此代码有效,而不必为每个表创建自定义bean,从而与物理数据模型紧密耦合。

                    <p:column headerText="Date" sortBy="#{r.getValue('date')}">
                        <h:outputText value="#{r.getValue('date')}" />
                    </p:column>

2 个答案:

答案 0 :(得分:2)

您希望它工作的方式与p:dataTable中的工作方式无关。我不确定普通直接(非延迟)过滤的工作方式。我从未使用过它,并且我总是implement lazy loading使用很多基类,因此很容易为不同的实体等实现,并为我提供了完全的控制权(OptimusFaces在这里提供帮助)

对于LazyDataModel,您需要在其中放置“ EL”的sortBy属性并未真正评估为EL。不在6.2中,但iirc也未在4.0中。实际上,您在其中放置的EL带有“#{..}”标记,并在此处期望的点上分开。生成的零件将在过滤器属性中传递给load方法。

所以

sortBy="#{bla.myAttribute}"` 

作为

传递给load方法。
myAttribute 

在展示柜中的LazyDataModel.java中可以看到(对于过滤btw同样如此)。

@Override
public List<Car> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
    List<Car> data = new ArrayList<Car>();

    //filter
    for(Car car : datasource) {
        boolean match = true;

        if (filters != null) {
            for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                try {
                    String filterProperty = it.next();
                    Object filterValue = filters.get(filterProperty);
                    String fieldValue = String.valueOf(car.getClass().getField(filterProperty).get(car));

                    if(filterValue == null || fieldValue.startsWith(filterValue.toString())) {
                        match = true;
                }
                else {
                        match = false;
                        break;
                    }
                } catch(Exception e) {
                    match = false;
                }
            }
        }

        if(match) {
            data.add(car);
        }
    }

    //sort
    if(sortField != null) {
        Collections.sort(data, new LazySorter(sortField, sortOrder));
    }

    //rowCount
    int dataSize = data.size();
    this.setRowCount(dataSize);

    //paginate
    if(dataSize > pageSize) {
        try {
            return data.subList(first, first + pageSize);
        }
        catch(IndexOutOfBoundsException e) {
            return data.subList(first, first + (dataSize % pageSize));
        }
    }
    else {
        return data;
    }
}

(在LazySorter中,对“汽车”类使用与过滤相同的反射:Car.class.getField(sortField).get(...),这意味着“ EL”中的整个第一部分被剥离了。因此,您可以放在假货前面。

这使您可以完全按照自己的意愿去做,而不是

sortBy="#{r.getValue('date')}"

只需使用

sortBy="#{myFakePrependeSomething.date}"

如果要对对象的字段进行排序,请使用

sortBy="#{myFakePrependeSomething.item.date}"

,然后传入“ item.date”,您只需要进行反射即可首先获取“ item”字段,然后获取日期。 OptimusFaces可以帮助您。

答案 1 :(得分:0)

我无法引入 OptimusFaces,所以我必须使用 LazySorter 的比较方法:

说清楚:这与 primefaces 提供的示例比较方法开箱即用:

     <p:column headerText="Id" sortable="true" sortBy="#{obj.id}" filterable="true" filterMatchMode="contains" filterBy="#{obj.id}">
            <h:outputText value="#{obj.id}"></h:outputText>
        </p:column>

这不会:

 <p:column headerText="Vorname" sortable="true" sortBy="#{obj.person.vorname}" filterable="true" filterMatchMode="contains" filterBy="#{obj.person.vorname}">
            <h:outputText value="#{obj.person.vorname }"></h:outputText>
        </p:column>

因为传递给比较器的 sortField 是“obj.person.vorname”,而 samplemethod 只找到父对象的字段,如下所示:

  Field[] userFields = Obj.class.getDeclaredFields();
         for (Field field : objFields) {

             if (field.getName().equals(sortField)) {
                 field.setAccessible(true);
                 value1 = field.get(cp1);
                 value2 = field.get(cp2);
             }
         }...

所以要获取孩子的字段,

 if(sortField.contains("person.")){
         Field[] personFields = Personen.class.getDeclaredFields();
         String pSortField = sortField.substring(7, sortField.length());

         for(Field pField : personFields){
             if(pField.getName().equals(pSortField)){
                 pField.setAccessible(true);
                 value1 = pField.get(cp1.getPerson());
                 value2 = pField.get(cp2.getPerson());
             }
         }
     }
     else if(... do it like bevore ....

也许有人可以提供一种更“反思”的方式来做这件事,这里使用“substing”让我很困扰……一个更通用的方法会更好……

顺便说一句。现在是primefaces 8