[英]Overriding Tapestry's Grid column sorting behvior
我有一个页面使用Grid表,其中可以对一个或多个列进行排序。 问题是挂毯似乎按ASCII值排序,这意味着AZ在az之前。 我希望对它进行排序,以使A和a在Z和z之前,或者是真正的字母而不是ASCII字母。
我可以在setupRender阶段正确地对值进行排序,但是问题是用户可以随时单击列标题中的排序图标,并且列的排序方式将恢复为ASCII方式。
我查看了Grid,GridSortModel和ColumnSort的文档,发现没有任何有用的方法可以替代此行为。 我对挂毯非常陌生,但是到目前为止文档对您没有帮助,而且我找不到在线上回答此问题的另一个问题。
我使用的挂毯版本为5.3.6。
谢谢。
编辑:这是一些更多的上下文。 网格是在.tml文件中定义的,如下所示:
<table t:type="grid" t:id="productGrid"
model="productModel" source="products" row="product"
class="product-grid" inPlace="true"
pagerPosition="both" style="width: 90%"
include="name,processors,actions" >
然后在java文件中定义产品列表,如下所示:
@Inject
private IProductConfigurationService _productService;
@Persist
private Set<IProductConfiguration> _products;
. . . .
_products = _productService.getProductConfigurations();
然后,通过修改_products,我可以修改表/网格的顺序。
好吧,我终于弄明白了。 挂毯对我来说还是个谜,但是有人用IRL帮助了我:
您必须用自己的替换默认的GridDataSource类。 注意,此代码可能可以重构,但是我现在使用的代码如下所示:
public class MyGridDataSource implements GridDataSource {
private final List list;
public MyGridDataSource(final Collection collection) {
assert collection != null;
list = CollectionFactory.newList(collection);
}
public int getAvailableRows() {
return list.size();
}
public void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints) {
for (SortConstraint constraint : sortConstraints) {
final ColumnSort sort = constraint.getColumnSort();
if (sort == ColumnSort.UNSORTED) {
continue;
}
final PropertyConduit conduit = constraint.getPropertyModel().getConduit();
final Comparator valueComparator = new Comparator<Comparable>() {
public int compare(Comparable o1, Comparable o2) {
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
String name1 = (String) o1;
String name2 = (String) o2;
for (int i = 0; i < Math.min(name1.length(), name2.length()); i++) {
Character c1 = name1.charAt(i);
Character c2 = name2.charAt(i);
Character C1 = Character.toUpperCase(c1);
Character C2 = Character.toUpperCase(c2);
int diff = 0;
// if the letters are different and different case, then....
// this allows "a" to come before "Z" for instance
if (c1.compareTo(c2) != 0 && C1.compareTo(C2) != 0 &&
c1.compareTo(c2) != C1.compareTo(C2)) {
diff = C1.compareTo(C2);
} else {
diff = c1.compareTo(c2);
}
if (diff != 0) {
return diff;
}
}
// shorter strings come first
return name1.length() - name2.length();
}
};
final Comparator rowComparator = new Comparator() {
public int compare(Object row1, Object row2) {
Comparable value1 = (Comparable) conduit.get(row1);
Comparable value2 = (Comparable) conduit.get(row2);
return valueComparator.compare(value1, value2);
}
};
final Comparator reverseComparator = new Comparator() {
public int compare(Object o1, Object o2) {
int modifier = sort == ColumnSort.ASCENDING ? 1 : -1;
return modifier * rowComparator.compare(o1, o2);
}
};
Collections.sort(list, reverseComparator);
}
}
public Class getRowType() {
return list.isEmpty() ? null : list.get(0).getClass();
}
public Object getRowValue(int index) {
return list.get(index);
}
public List getList() {
return list;
}
}
好的,那么您就可以使用此类作为数据类型。 (如果您未指定,tapestry显然会使用DefaultGridDataSource自动包装您的网格数据)。
这意味着上面的代码只需更改为:
@Inject
private IProductConfigurationService _productService;
@Persist
private MyGridDataSource _products;
. . . .
_products = new MyGridDataSource(productService.getProductConfigurations());
这是覆盖默认排序行为的一种方法。 大概应该比这容易。 但这有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.