JDev Ver. 11.1.1.3.0
问题场景:
使用Carousel控件,希望在 backing bean 中的CarouselSpinListener方法中设置Carousel控件binding的Iterator对象的CurrentRow,进而达到改变Model层对象CurrentRow的目的。且不希望使用AM端暴露client方法的实现方式。
问题分析:
以前遇到需要设置AM中VO实例的currentRow时,总是在AM中创建一个client方法,接受参数进行对应VO的currentRow设置。其实当DataControl中的对象binding到client端生成XXIterator(实例继承于JUIteratorBinding)后,在Iterator对象上已存在两个方法 setCurrentRowWithKey(String) 及 setCurrentRowWithKeyValue(String) 。如图
这两个方法在使用上的问题为:它们均只接受一个String类型变量。
通过查看adfm.jar中的源代码,发现JUIteratorBinding上的这两个方法均调用至DCBeanDataControl类中的同名方法。同时在DCBeanDataControl中还有一个未暴露的setCurrentRowWithKey(DCIteratorBinding iter, Key key) 方法可供调用。首先尝试调用DCBeanDataControl中的setCurrentRowWithKey方法,代码片段代码如下:
public void carouseSpin(CarouselSpinEvent carouselSpinEvent) {
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
JUIteratorBinding obj = (JUIteratorBinding)app.evaluateExpressionGet(fc, “#{bindings.itemsIterator}”, Object.class);
this.carousel.setRowKey(carouselSpinEvent.getNewItemKey());
Key currentRowKey = (Key)((List)carouselSpinEvent.getNewItemKey()).get(0);
DCDataControl dc = obj.getDataControl();
dc.setCurrentRowWithKey(obj, currentRowKey);
}
经测试该方法可行,但由代码可见,该方法将DataControl对象取到了backing bean中使用,破坏了DataControl - DataBinding - View这种结构。
通过查看JUIteratorBinding类中setCurrentRowWitheKey及setCurrentRowWithKeyValue两个方法的源代码,对两个方法作出如下总结:
setCurrentRowWithKeyValue(String) 当对应Iterator的model层对象声明为单主键时,该方法可用于设置Iterator当前行。传入参数为对应主键值。
setCurrentRowWithKey(String) 当对应Iterator的model层对象声明为单主键多主键时,需要将主键Key对象编码后以String传入。
代码片段:
public void carouseSpin(CarouselSpinEvent carouselSpinEvent) {
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
JUIteratorBinding obj = (JUIteratorBinding)app.evaluateExpressionGet(fc, “#{bindings.itemsIterator}”, Object.class);
this.carousel.setRowKey(carouselSpinEvent.getNewItemKey());
Key currentRowKey = (Key)((List)carouselSpinEvent.getNewItemKey()).get(0);
obj.setCurrentRowWithKey(RepConversion.bArray2String(currentRowKey.toByteArray(true)));
}