p:dataTable 在 PrimeFaces 4.0 中没有 getter 的排序 [英] p:dataTable sorting without getters in PrimeFaces 4.0

查看:35
本文介绍了p:dataTable 在 PrimeFaces 4.0 中没有 getter 的排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个显示数据的数据表,但排序不起作用.

I have a data table that presents data but sorting does not work.

问题是,这些记录没有 getFieldName 获取器,而是 getValue('FieldName').这使我无需重新编译即可更改架构.

The problem is, these records don't have getFieldName getters, but getValue('FieldName'). This allows me to change the schema without recompiling.

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

For example, one such field is a date.

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

I would like some trick to make this code work, without having to create custom beans for every table, hence tightly coupled to the physical data model.

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

推荐答案

您希望它的工作方式不是它在 p:dataTable 中的工作方式.我不确定普通的直接(非懒惰)过滤是如何工作的.我从来没有用过,我总是实现延迟加载有很多基类,所以很容易为不同的实体等实现,并让我完全控制(OptimusFaces 在这里有帮助)

The way you want it to work is not how it is going to work in the p:dataTable. I'm not sure how the plain direct (non-lazy) filtering works. I've never used that and I always implement lazy loading with a lot of base classes so it is easy to implement for different entities etc and gives me full control (OptimusFaces helps here)

对于 LazyDataModel,您需要放置 'EL' 的 sortBy 属性并未真正评估为 EL.不在 6.2 中,但 iirc 也不在 4.0 中.事实上,你放在那里的 EL 去掉了 `#{..} 并在那里预期的点上分开.结果部分将传递给过滤器属性中的 load 方法.

For LazyDataModel, the sortBy attribute where you need to put 'EL', is not really evaluated as EL. Not in 6.2 but iirc also not in 4.0. In fact the EL you put in there is stipped of the `#{..} and split on the dot that is expected in there. The resulting part is passed on to the load method in the filter properties.

所以

sortBy="#{bla.myAttribute}"` 

作为

myAttribute 

正如在展示中的 LazyDataModel.java 中所见(顺便说一句,过滤也是如此).

As can be seen in LazyDataModel.java in the showcase (same is true for the filtering 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' 类上使用了与过滤相同的反射:Car.class.getField(sortField).get(...) 以便意味着'EL'中的整个第一部分都被剥离了.因此你可以把任何假的东西放在前面.

(in the LazySorter, the same reflection is used on the 'Car' class as is done for the filtering: Car.class.getField(sortField).get(...) so that implies the whole first part in the 'EL' is stripped. And hence you can put any fake thing in front.

这使得完全可以做你想做的事,而不是

This makes it possible to do exactly what you want but instead of

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

就用

sortBy="#{myFakePrependeSomething.date}"

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

And if you want to sort on a field of an object use

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

然后传入`item.date',您只需要进行反射以首先获取'item'字段,然后获取日期.OptimusFaces 对此有所帮助.

and then `item.date' is passed in and you just have to do the reflection to first get the 'item' field and then the date. OptimusFaces helps with this.

这篇关于p:dataTable 在 PrimeFaces 4.0 中没有 getter 的排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆