"在ManagedBean中调用AppModuleImpl中自定义方法的两种方式"
平台: Jdev11.1.1.7.0
- *AM*中创建自定义方法sayHello
{% codeblock lang:java %}
public void sayHello(String value){
System.out.println("hello world..."+value);
}
-
暴露该方法以便在ManagedBean中调用
-
从Data Controls中将该方法拖到页面生成Bindings或者手工添加该Bindings。
-
为了测试方便,创建了一个inputText,并绑定该inputText的valueChangeListener为ManagedBean中的valueChange方法.
{% codeblock lang:java %}
public void valueChange(ValueChangeEvent valueChangeEvent) {
String newValue = valueChangeEvent.getNewValue().toString();
//方法一:调用bindings
BindingContainer bindings = ADFUtils.getBindingContainer();
OperationBinding refreshChecklist = bindings …
Read More
"关于ApplicatoinModule类型总结"
平台:Jdev11.1.2.3.0
AM的类型
1. Root AM
2. Nested AM
3. Shared AM
三种类型AM的比较
首先谈谈RootAM的数量,RootAM原则上来说越少越好,因为当用户访问工程的时候数据库连接数量会根据RootAM的数量成倍增加极大地增加了数据库的压力。但是很多时候由于业务的复杂性,单一的AM无法满足实际开发的需求,所有的业务逻辑都写在一个AM里极不利于多个团队的协同开发。
这个时候NestedAM就发挥其作用了,NestedAM是共享其父类RootAM的数据库连接的,所以不会额外增加连接数量,利用NestedAM可以将业务逻辑拆分开来,每个团队都可以使用自己单独的NestedAM,团队之间彼此冲突地可能性大大减少。
再说SharedAM,大型项目中很多模块的功能是通用的,比如LOV或者一些在使用中基本不需要改变的固定配置数据等,这类数据对项目所有访问用户都是固定的,可以使用SharedAM来维护这类型数据。
三种类型的AM的创建方法
- RootAM,默认创建的AM即是RootAM
-
NestedAM创建方法
先创建两个RootAM(deptAm,empAm),分别拥有VO instance(DeptVO,EmpVO);
再创建一个RootAM(rootAM),双击该rootAM,在Data Model标签页中 …
Read More
"ADF类似心跳程序实现"
使用ADF框架开发WEB应用时,其中令人苦恼的一个需求就是:在两个页面同时展示一个数据源时,如果其中一个页面对数据源作了变更操作,另外一个页面没办法自动获得变更后的数据,需要手工刷新页面才能得到变更后的新数据源。
其实ADF自带的<af:poll/>
组件即可实现此需求。
例子:
- 创建一个可更新的af:table 基于HR的Department表
可以更改表数据并提交,用多浏览器窗口打开该页面来模拟多用户操作。
将<af:poll/>
控件拖入到页面中,控件属性设置如下:
设置间隔为1分钟,并绑定PollListener
- 给该页面绑定ManagedBean,并添加PollListener,方法内容如下:
{% codeblock lang:java %}
public void heartBeat(PollEvent pollEvent) {
System.out.println("start poll...");
DCIteratorBinding it = ADFUtils.findIterator("Departments1Iterator");
ViewObject vo = it.getViewObject();
vo.executeQuery …
Read More
"ADF学习总结(一)"
改变VO查询条件
- 使用WhereClause改变查询条件
- 使用Criteria改变查询条件
- 使用Bind Variables改变查询条件
使用WhereClause改变查询条件
通过VO对象的setWhereClause方法改变查询条件
{% codeblock lang:java %}
DCIteratorBinding dc = ADFUtils.findIterator("DepartmentsView1Iterator");
ViewObject vo = dc.getViewObject();
vo.setWhereClause(" 1=1 ");
vo.executeQuery();
addWhereClause是在原有whereClause基础上添加新的查询条件;
跟setWhereClause替换原有whereClaue不同;
使用ViewCriteria改变查询条件
事先在创建VO的时候,定义好几种Criteria:DepartmentsViewCriteria
{% codeblock lang:java %}
DCIteratorBinding dc = ADFUtils.findIterator("DepartmentsView1Iterator");
ViewObject vo = dc.getViewObject();
ViewCriteriaManager vcm=vo.getViewCriteriaManager …
Read More
"getRowAtRangeIndex(int)方法的局限性"
导出VO中的数据到EXCEL中时,循环VO中的Row,写入HSSFRow,是通过getRowAtRangeIndex(int)方法循环取Row,代码如下:
{% codeblock lang:java %}
ViewObject vo8=am.findViewObject("ChReport1VO1");
if(vo8!=null)
{
int rowcount8=vo8.getRowCount();
for(int i=0;i<rowcount8;i++)
{
Row vo_row8=vo8.getRowAtRangeIndex(i);
//...TODO
}
}
这样如果VO里有300条数据,但是pageRange设置为100,这里其实只能取到第一页的100条数据,想要导出所有300条数据则需要一页一页导出,很麻烦。于是考虑不用getRowAtRangeIndex方法取ROW数据,改用RowSetIterator。
{% codeblock lang:java %}
ViewObject vo8=am.findViewObject("ChReport1VO1 …
Read More
adf:tree做的树菜单如何过滤子节点的数据?
需求:项目中的树菜单需要权限用户的权限过滤显示子菜单,通过用户所在的用户组可以查看的页面ID(List)过滤子节点
解决方案:
因为树是通过viewLink关联自身的VO生成的,想在AM里添加方法,对VO进行过滤处理把结果返回。
但实现起来比较麻烦,调用方法之后要刷新页面,初始化的树数据过滤处理困难。
于是想重写VO的方法看能不能在VO层就过滤掉子节点。重写createViewLinkAccessorRS,此方法返回ViewLink的结果,也就是菜单的子节点数据
@Override
protected ViewRowSetImpl createViewLinkAccessorRS(AssociationDefImpl associationDefImpl,
ViewObjectImpl viewObjectImpl,
Row row,
Object[] object) {
ViewRowSetImpl viewRowSetImpl =
super.createViewLinkAccessorRS(associationDefImpl, viewObjectImpl,
row, object);
int count = 0;
// getList()拿到可以查看的pageId的列表,对比Row中的pageId属性,如果在List中存在,就取该Row,如果不存 //在,表示此子节点不予以显示,remove掉
if (this …
Read More
表内的checkbox当数据量大时发现部分行勾选不中
测试发现,当数据只有25行的时候,都可以正常勾选,超过25行的数据,总是勾选不中。
问题产生原因:
由于自定制的checkbox是设置了immediate=true 即时给数据行的checkbox字段赋值。
VO的rangeSize 默认是25,
因此导致25条数据内是可选。25条之外的数据初始时没有取出来,因此对这些没取的数据行设置checkbox自然就不生效了(展现出来就是checkbox勾选不中)
解决方案:
修正VO的rangeSize为-1,查询全部,即可解决此问题。
Read More
关于定制validator
一个时刻字段,要求输入00:00-12:60这样的时刻范围
使用如下的正则表达式,过滤掉了不合规则的数字之后,还差一个逻辑,结束时刻不能小于开始时刻,比如:10:00-9:00这样的输入也是不合法的。正则太折磨眼力了,应该也是可以做到这点的吧,为了偷懒,就定制个validator来处理这个点。
<af:validateRegExp pattern="([0-1][0-9]|2[0-4])\:([0-5][0-9]|60)\-([0-1][0-9]|2[0-4])\:([0-5][0-9]|60)" messageDetailNoMatch="请输入时刻,例如 00:00-24:60 " hint="请输入时刻,例如 00:00-24:60"/>
Step1。创建一个ValidatorTime类实现Validator接口
Read More
关于ManagedBean中多次执行构造方法时的问题
有时候需要在初始化时执行一些查询,但发现会多次执行。需要在构造方法里添加一行代码避免页面点击时多次执行初始化。
if (!(Boolean)ADFUtils.getBindObject("adfFacesContext.postback")) {
init();
}
通过页面是否postback来控制只初始化一次。
Read More
关于selectBooleanCheckbox 的问题
页面的 selectBooleanCheckbox 选择后,总提示 不是数字(组件value是 true 或 false,数据库存的是Number),怎么解决
方案有三个
1。如果是基于表的Number字段(假设字段名是Flag,值是1或者0),想生成selectBooleanCheckbox ,可以重写这个VO的的 setFlag()跟getFlag()方法如下:
public void setFlag(Boolean value){
this.flag=value==true?1:0;
}
public Boolean getFlag(){
return this.flag==0?false:true;
}
2。设置valueChangeListener.
在valueChange方法里捕获当前selectBooleanCheckbox 的值,然后转化成Number类型的传给VO
3。如果是只读的表,可以在UI上通过EL表达式处理。
Read More