我们都知道,使用VO生成的Table如果是单选的话,页面运行会定位在第一行,我们通过VO.getCurrentRow()也是第一行的row.当鼠标定位到其它行的时候VO.getCurrentRow()也是定位的那一行。
很多情况我们先选择某一行然后对table中的vo做了些操作,比如查询后再刷新table,会发现table又重新定位到第一行去了,这就可能会有如何查询vo后还是定位在刚才的选择的行上。要解决这个技术问题首先需要理解Binding和UI之间是如何交互的,比如当我们鼠标定位在某一行时,为什么通过VO.getCurrentRow()也是定位的那一行?
首先我们可以肯定的是:table中的数据是来源于vo的,而table的value是collectionModel的一个实例。通过代码我们发现collectionModel与vo二个类一点关系也没有!通过对Binding层的理解我们发现VO的数据放在上绑定迭代器上了,比如:xxxIterator,我们可以通过pageDef.xml可以看到.那么我们是不是可以推测,collectionModel是读取xxxIterator中的数据呢?ADF内部到底是怎么做的呢?
其它,如果上面的理解成立的话,我们又可以推测,UI层的类,比如上面的collectionModel与pageDel.xml他们是可以交互的!不然就无法解释我们为什么通过VO.getCurrentRow()得到的行与鼠标定位行完全一致的结果!所以,解决我们的问题在于找到他们是如何交互的!而这个线索就是table中的selectionListener事件,ADF通过解析这个事件来实现二者的交互同步!
顺着前面的思路,我们去熟悉RichTable类。通过了解这个类的方法后我们发现有些方法看名称就大概知道含义了。具体就不一一的举例了。知道大概的解决思路后,我们把问题缩小到四个主要的类上,这二个其实已经提到了,它们分别是:RichTable,collectionModel,JUCtrlHierBinding,JUIteratorBinding.前二个类是UI层的绑定类后二个是Binding层的类,那么是不是collectionModel,JUCtrlHierBinding相互转化或者相互读取数据来实现二者的交互呢?当然不是的!而是FacesJUCtrlHierBinding!
好了,讲完理论了得说讲究怎么实现!
首先你得把定位的行的Key先保存起来!然后做完业务处理后通过这个Key来构建UI Table中定位行和Binding层xxxIterator的当前行即可!代码如下:
if (oldSelectKey != null) {
//绑定层行定位
JUCtrlHierBinding jubing = (JUCtrlHierBinding) cm.getWrappedData();
jubing.getIteratorBinding().setCurrentRowWithKey(oldSelectKey.toStringFormat(true));
//UI Table选择行定位
RowKeySet rs = new RowKeySetImpl();
ArrayList list = new ArrayList(1);
list.add(oldSelectKey);
rs.add(list);
_table.setSelectedRowKeys(rs);
ADFUtils.refresh(_table);
}
简单吧!