2011年8月7日星期日

ADF_103:何时应该Enable Commit按钮?如何Enable?

Commit按钮的disabled默认属性值为"#{!bindings.Commit.enabled}",注意这里有个叹号,表示非bindings.Commit.enabled。
即如果bindings.Commit.enabled=true,表示Commit按钮可以使用,这时disable=false;反之,bindings.Commit.enabled=false,表示Commit按钮不可以使用,这时disable=true。
disabled属性可以更加精准地控制Commit按钮的行为:只有当需要使用Commit按钮才使用。因为Commit操作往往需要保存数据到数据库,操作相对费时,因此最好不要让用户随便点击。

需要Enable时才Enable,其判断的依据就是表单数据是否已经更改。如果用户打开一个可编辑表单只是看看,不做任何修改,这时就不应该允许用户点击 Commit按钮。

实际应用中,在做其它操作时,我们也需要判断数据是否已经更改,比如:用户修改了某个表单,没有提交,然后直接转到其它页,这时我们应该提醒它数据已经修改,是否保存?
也就是说,我们需要在Manage Bean中判断bindings.Commit.enabled的值,方法如下:

public boolean isCommitEnabled() {
Boolean commitState = (Boolean)JSFUtils.getManagedBeanValue("bindings.Commit.enabled");
boolean commitEnabled = commitState != null ? commitState.booleanValue() : false;
return commitEnabled;
}

在看过一些老外的例子后,发现也有这样判断断数据是否已经更改的,感觉这个判断更为底层,因为是在AM上判断的,是否只要AM上的VO发生了改变,都可以用这个方法监测到?
我目前也太清楚,但做了个简单的实验后,发现这两种判断结果是一致的。
public boolean isDirty()
ApplicationModule am = ADFUtils.getDCBindingContainer().getDataControl().getApplicationModule();
return am.getTransaction().isDirty();
}

在使用ADF Commit按钮时,还有一个常见问题:当用户修改某一个表单项后,即使焦点转移后,Commit按钮也不会被Enable,这是为啥呢?
经过实验,需要增加两个参数:
(1)增加autoSubmit="true" 。
(2)刷新Commit按钮。
方法一:通过增加valueChangeListener="#backingBeanScope.backing_main.onValueChange}"
public void onValueChange(ValueChangeEvent valueChangeEvent) {
if (this.getCb1().isDisabled()) {
AdfFacesContext.getCurrentInstance().addPartialTarget(this.getCb1());
}
}
方法二:设定Commit按钮的PPR,指向该表单项,这样当该表单项变动后,会局部刷新Commit按钮。

一个矛盾而有意思的现象是:虽然这时Commit按钮被Enable了,但bindings.Commit.enabled却等于fasle。按照这个值,disable="#{!bindings.Commit.enabled}"应该等于true。
留待以后查证吧。

参考文献:
1. http://andrejusb.blogspot.com/2010/01/auto-commit-use-case-in-oracle-adf-11g.html
2. http://blogs.oracle.com/smuenchadf/examples/138
3. http://forums.oracle.com/forums/thread.jspa?threadID=833597
4. http://forums.oracle.com/forums/thread.jspa?threadID=597254

没有评论: