下面的特性已经被更改:
HtmlView基于原来代码的实现已经deprecated
Cell接口更简单
增加RowTag
AutoGenerateColumns变为singleton,更易添加列属性
Extended Attributes方法名变更
TableTag的collection属性被删除
BaseModel更名为TableModel
Properties和ResourceBundle现在为Preferences和Messages
pageContext被Context接口代替
Limit和LimitFactory的语法变更,更易于使用
TableTag的saveFilterSort属性被state属性代替
ColumnTag的showTotal属性被calc属性代替
search图片的名称变为filter
FormTag/InputTag为deprecated
RetrieveRowsCallbacks、FilterRowsCallback、SortRowsCallback都变为singletons
我把和旧的view相关的代码:原始的view、cell和相关代码放到deprecated文件夹。 原因是新的view代码非常成功,所以没有必要使用旧的代码。使用新代码构建定制view请参考 view包中的HtmlView或CompactView。
Cell接口已经改变,原因是想结束混乱以提高灵活性。以前对于如何处理区分html和export显示值 不是十分明显。现在Column值设置html,Column的propertyValue设置export。另外因为Column值和 propertyValue值被重写。现在他们在view中是不可见的。
cell现在是singleton并且不再线程安全,因此不要定义任何类变量。改变的原因是为 了Cell接口能更简单地被使用。init()和destroy()方法作为singleton更灵活但是处于一种混乱的状态。
Cell接口如下:
public interface Cell {
/**
* The display that will be used for the exports.
*/
public String getExportDisplay(TableModel model, Column column);
/**
* The html that will be displayed in the table.
*/
public String getHtmlDisplay(TableModel model, Column column);
}
现在得到导出和html显示存在明显的区别。更重要的,需要返回字符串。列值和属性值不再 需要设置。另一个细微的区别是:BaseModel已经被TableModel取代。这种改变是的不再需要一个 基础包(base package),这意味着不再需要BaseModel。
cell变为singleton不会导致使用复杂,如果你定义了任何类变量只需要把他们放到正确的 方法那么他们就能被任何其他方法使用。
BaseCell被删除因为不再需要添加任何值。替代的是AbstractCell,虚拟方法 getCellValue被用来返回cell的值。这种方法非常容易使用并不需要关心markup。查看 AbstractCell也是有意义的,你会发现这代码实现的多么简单。然而,很多时候需要做的仅仅是 实现Cell接口:
DisplayCell:
public class DisplayCell extends AbstractCell {
public String getExportDisplay(TableModel model, Column column) {
return column.getPropertyValueAsString();
}
protected String getCellValue(TableModel model, Column column) {
return column.getValueAsString();
}
}
AbstractCell:
public abstract class AbstractCell implements Cell {
public String getExportDisplay(TableModel model, Column column) {
return getCellValue(model, column);
}
public String getHtmlDisplay(TableModel model, Column column) {
HtmlBuilder html = new HtmlBuilder();
CellBuilder.tdStart(html, column);
CellBuilder.tdBody(html, getCellValue(model, column));
CellBuilder.tdEnd(html);
return html.toString();
}
/**
* A convenience method to get the display value.
*/
protected abstract String getCellValue(TableModel model, Column column);
}
RowTag<ec:row> 现在被需要,它被用来替代columns。 现在看来它一直被需要。它不知道表中到底有多少列,最近重构的时候我通过 Table -> Row -> Column使结构固定来合并得到更好的灵活性。将来我可能提供更多的 特性,因为我知道eXtremeTable有着清晰的架构。
典型的eXtremeTable如下:
<ec:table
items="presidents"
var="pres"
action="${pageContext.request.contextPath}/presidents.run"
>
<ec:row>
<ec:column property="name"/>
<ec:column property="term"/>
</ec:row>
</ec:table>
15.1.4. AutoGenerateColumns
AutoGenerateColumns得到了很大的提高,现在你只需要设置你需要的属性。 当你添加列到ColumnHandler使,defaults将别自动调用。
AutoGenerateColumns为singleton并且不是线程安全的,因此不要定义任何类变量。
现在它的实现可能如下:
public class AutoGenerateColumnsImpl implements AutoGenerateColumns {
public void addColumns(TableModel model) {
Iterator iterator = columnsToAdd().iterator();
while (iterator.hasNext()) {
Map columnToAdd = (Map) iterator.next();
Column column = new Column(model);
column.setProperty((String) columnToAdd.get(PROPERTY));
column.setCell((String) columnToAdd.get(CELL));
model.getColumnHandler().addAutoGenerateColumn(column);
}
}
}
15.1.5. Extended Attributes
addExtendedAttributes方法重命名使得如何使用这个特性更清晰。 因此RowTag的addExtendedAttributes现在变为addRowAttributes,ColumnTag变 为addColumnAttributes,TableTag变为addTableAttributes,ExportTag变 为addExportAttributes。另外你参考正确的model bean(它的实现更清晰), 将知道如何添加属性到你的cell、view.....
使用ExportCsvTag的示例如下:
public void addExportAttributes(Export export) {
String view = export.getView();
if (StringUtils.isBlank(view)) {
export.setView(TableConstants.CSV);
export.setImageName(TableConstants.CSV);
}
export.addAttribute(CsvView.DELIMITER, getDelimiter());
}
为了得到delimiter属性值你只需要从Export bean中get它:
Export export = model.getExportHandler().getCurrentExport();
String delimiter = export.getAttributeAsString(DELIMITER);
现在你需要在ExportTag中覆盖它,你只需要调用setter方法。如果是新的属性,那么使用 可以和前一版一样使用addAttribute()方法。为了得到值,首先从ExportHandler得到Export, 然后调用需要的getter方法。这和使用其它tags一样。
在RowTag和ColumnTag中增加了两个新的callback方法:modifyRowAttributes和 modifyColumnAttributes,因此你可以在rows/columns被处理时改变属性值。
15.1.6. TableTag的collection属性
TableTag的collection属性被删除,现在变为三个新属性:tableId、items和var。 因为我按照标准的JSTL命名,你应该能够根据这些名称知道他们的作用。tableId属性 被用来作为表的唯一标识,items属性用来表示从各种servlet的scopes里取得的集合, var属性表示你将使用EL编写脚本的名称。
依赖你的需要来决定如何使用新的属性,tableId用来唯一标识表。如果你的页面上只使用了 一个eXtremeTable并且不使用Limit特性,那么你根本不需要定义它。默认的表示名为'ec';如果使用 Limit特性你也可以使用'ec'这个名称。然而,如果的一个JSP页面上同时使用两个eXtremeTables你就 需要使用tableId来唯一标识他们。var属性被用来你将使用EL编写脚本的名称。items属性用来表示从 各种servlet的scopes里取得的集合,而且现在非常健壮。你现在能nest集合到另外的对象,或者nest你想的 深度。
取得集合的语法如下:
<ec:table items="command.myObject.myCol" />
本示例将从命令对象(command object)取得myCol集合。
<ec:table items="myCol" />
本示例中将根据名称自动取得集合,就像以前版本的collection属性一样。
BaseModel被重命名为TableModel,这是因为已经不需要一个基础包(base package)了,这也 意味着不再需要BaseModel了。
15.1.8. Properties和ResourceBundle
web.xml文件中使用extremecomponentsPreferencesLocation属性取代extremecomponentsPropertiesLocation属性, properties现在被Preferences接口控制。在以后的版本,我将提供可选的xml文件配置。
eXtremeTable不再默认在顶层类路径(top level classpath)寻找 extremecomponents.properties文件。你应该在web.xml中使用设置context-param属性的 值为extremecomponentsPreferencesLocation,这将更为通用。
web.xml文件中使用extremecomponentsMessagesLocation属性取代extremecomponentsResourceBundleLocation属性, internationalization现在被Messages接口控制。
Properties和ResourceBundle属性根据table、row、column、export和filterare区分开。 在以前版本中每个属性都以'table'开头,现在每个属性关联到被使用的标签。另外poperty不再需要使用奇怪的下划线语法, 而是使用dot来强调。
下面为properties文件的示例:
table.imagePath=/extremesite/images/*.gif
table.rowsDisplayed=12
column.parse.date=yyyy-MM-dd
column.format.date=MM/dd/yyyy
column.format.currency=$###,###,##0.00
[英文的属性文件示例如下:]
statusbar.resultsFound={0} results found, displaying {1} to {2}
statusbar.noResultsFound=There were no results found.
toolbar.firstPageTooltip=First Page
toolbar.lastPageTooltip=Last Page
toolbar.prevPageTooltip=Previous Page
toolbar.nextPageTooltip=Next Page
toolbar.filterTooltip=Filter
toolbar.clearTooltip=Clear
toolbar.clearText=Clear
toolbar.firstPageText=First
toolbar.lastPageText=Last
toolbar.nextPageText=Next
toolbar.prevPageText=Prev
toolbar.filterText=Filter
column.headercell.sortTooltip=Sort By
column.calc.total=Total
column.calc.average=Average
TableModel (以前的BaseModel)不再直接访问pageContext,取而代之的是使用Context接口, 默认的被pageContext支持。直接访问pageContext是一个不好的实现,Context提供你需要从不同servlet scopes中 取得需要属性值的所有方法。然而,如果你需要直接访问背后的对象,可以使用getContextObject()方法。
15.1.10. Limit和LimitFactory
Limit和LimitFactory现在都是接口,以前版本的实现不如我想象的简单。然而, Limit对象的方法命名和以前版本的一样,因此你以前的代码也能很好的工作。
我两个Limit实现重构为一个,但是仍有两个LimitFactory实现, 从coding的观点用户只要使用一个 实现,但是它必须兼容以前的版本。现在只有一个Limit实现我重命名为TableLimit。同时,因为Limit特性 依赖Context而不是request,我重命名工厂类(TableLimitFactory)来reflect它。
Limit在导出时正确地显示行信息,Limit具有一个isExported()方法。
使用Limit和LimitFactory的示例如下:
Context context = new HttpServletRequestContext(request);
LimitFactory limitFactory = new TableLimitFactory(context, tableId);
Limit limit = new TableLimit(limitFactory);
设置row属性,仅设置totalRows和默认的行显示:
limit.setRowAttributes(totalRows, DEFAULT_ROWS_DISPLAYED);
RequestLimitFactory具有另一个如果没有指定tableId将设置为ec的构造函数:
Context context = new HttpServletRequestContext(request);
LimitFactory limitFactory = new TableLimitFactory(context);
15.1.11. TableTag的saveFilterSort属性
saveFilterSort属性被state属性取代,state属性参照State接口并能插接不通的关于 如何保存表状态的实现。
State接口如下:
public interface State {
public void saveParameters(TableModel model, Map parameters);
public Map getParameters(TableModel model);
}
表新增了两个属性:state和stateAttr。state属性使用预设的四种 状态(default、notifyToDefault、persist和notifyToPersist)之一, 你也可以插接自己的实现。default状态不维持任何状态;persist状态没有任何参数传入,将一直维持表的状态; notifyToDefault状态将一直维持表的状态直到你传入参数告诉它回到default状态;notifyToPersist状态 将一直维持当前状态直到你传入参数告诉它维持persisted状态。stateAttr为指定参数提供了一条途径,你 也可以使用属性文件在全局范围内指定它。为了向后兼容,默认参数一直为useSessionFilterSort。
如果你想state按照不同方式工作你只要实现State接口,然后使用TableTag的state属性来指定实现类的 全路径。
15.1.12. ColumnTag的showTotal属性
列新增了两个属性:calc和calcTitle:
<ec:column property="data" calc="total" calcTitle="Total:" />
calc属性实现具有唯一方法的Calc接口:
public interface Calc {
public Number getCalcResult(TableModel model, Column column);
}
它传入model和column,并返回一个Number型的值。默认的实现为总计和平均值。
为了使用定制的Calc,只需要使用ColumnTag的calc属性来指定实现Calc接口的实现类的 全路径。
Calc为singleton并且不是线程安全的,因此不要定义任何类变量。
showTotal因为不再适用在新版中被删除,我也删除了表中的totalTitle。
search图片名从search变为filter。
15.1.14. FormTag / InputTag Deprecated
FormTag和InputTag现在为deprecated。他们在新的html视图(view)中不再被使用。
15.1.15. RetrieveRowsCallbacks、FilterRowsCallback、SortRowsCallback
Callbacks为singleton并且不是线程安全的,因此不要定义任何类变量。