2011年7月26日星期二

WebCenter_024:OmniPortlet使用指南之二:传递参数

实际开发中,经常会遇到这种场景:选中表格中的一行,刷新旁边的某个Portlet。
本实验就是针对此种情况,其它场景大家可以举一反三。
开发工具:JDeveloper 11.1.1.5.0。
首先完成《OmniPortlet使用指南之一:访问CSV数据

1. 实验准备:创建Schema
(1)sqlplus system/welcome1 @create_veeva_user.sql
grant connect, resource to veeva identified by veeva;
Exit;
(2)sqlplus veeva /veeva @create_contries_table.sql
create table countries (
country_id number primary key,
country_name varchar2(50),
continent varchar2(50),
currency varchar2(50)
);
insert into countries (country_id, country_name, continent, currency) values (1001,'France','Europe','Euro');
insert into countries (country_id, country_name, continent, currency) values (1002,'Italy','Europe','Euro');
insert into countries (country_id, country_name, continent, currency) values (1003,'USA','North America','US dollar');
insert into countries (country_id, country_name, continent, currency) values (1004,'Hungary','Europe','Hungarian forint');
insert into countries (country_id, country_name, continent, currency) values (1005,'Indonesia','Asia','Indonesian rupiah');
insert into countries (country_id, country_name, continent, currency) values (1006,'New Zealand','Oceana','New Zealand dollar');
insert into countries (country_id, country_name, continent, currency) values (1007,'Japan','Asia','Japanese yen');
insert into countries (country_id, country_name, continent, currency) values (1008,'Australia','Oceana','Australian dollar');
insert into countries (country_id, country_name, continent, currency) values (1009,'United Kingdom','Europe','British pound');
insert into countries (country_id, country_name, continent, currency) values (1010,'India','Asia','Indian rupee');
insert into countries (country_id, country_name, continent, currency) values (1011,'Brazil','South America','Brazilian real');
insert into countries (country_id, country_name, continent, currency) values (1012,'Kenya','Africa','Kenyan shilling');
commit;

2. 创建WebCenter Portal 应用

3. 在Portal应用中,新建一个ADF Model Project
不要在Portal Project创建Model层的东西,应该新建一个Model Project,从项目设计就体现出MVC的设计。
创建ADF Business Components from Tables:Contries。

4. 在Portal Project中,新建一个页面,拖放ContriesView,生成Read Only Table。

5. 查看页面的Bindings,展开左下角的Structure面板。
variables节点下的是页面变量(page variables),当拖放一个Portlet到页面时,JDeveloper会分析该Portlet有没有参数(portlet parameters)。
如果有,JDeveloper会自动创建对应的页面变量(page variables),就像我们在这里看到的情况:
OmniPortlet有5个参数,因此创建了5个对应的页面变量。
既然OmniPortlet中的参数全部来自于对应的页面变量,那剩下的事就变得简单了:
只要把组件中变量的值赋值给页面变量,页面变量会在赋值给对应的OmniPortlet中的参数。
好,下面我们就开始把组件中变量的值赋值给页面变量。


如果没有绑定CountryId,可以自己手工添加。

把#{bindings.CountryId.inputValue}赋值给OmniPortlet3_1_Param1的DefaultValue。

6. 启动并访问应用,修改OmniPortlet定制化选项中Filter。


7. 设置OmniPortlet的Parial Trigger属性,指向Table的id。

重新发布并运行Portal应用,发现点击表格的某一行时,右边的OmniPortlet并没有刷新。
经过反复检查,OmniPortlet配置没有错误,而是#{bindings.CountryId}无法成功赋值给OmniPortlet3_1_Param1的DefaultValue。
具体原因不明,日志中会报出一个警告:
无法将 PortletBinding OmniPortlet3_1上的参数Param1设置为非字符串或字符串数组的值。

花了一天的时间,查阅了大量文档和例子,都没有找到解决办法。
无奈之下,我写了一个Backing Bean,从BackingBean中获取#{bindings.CountryId}值,再赋给OmniPortlet3_1_Param1的DefaultValue。

Manage Bean的部分代码如下:
String currentCountryId = "1001";

public MyBackingBean() {
}

public String getCurrentCountryId() {
return JSFUtils.getManagedBeanValue("bindings.CountryId").toString();
}

public void setCurrentCountryId() {
currentCountryId =
JSFUtils.getManagedBeanValue("bindings.CountryId").toString();
}

现在,点击表格的某一行,右边的OmniPortlet会随着改变。
查看日志,那一行警告信息也消失了。


Project下载:Veeva_OmniPortlet_Parameter.7z

问题终于搞清楚了,都是CountryId字段类型惹的祸,换成CountryName就没有问题了。
如果你的JavaBean中使用Number型的字段,也会出同样的问题。
但问题是,CountryId本身就是Number型,如果一定要传CountryId字段的值,目前只能按照上面的方法通过一个ManageBean转发。
不知道有没有其它的好方法,我会继续关注此问题。

TestPortlet.7z

没有评论: