使用clientlistener和serverlistener刷新InlineFrame
十二月 9, 2008 in Oracle 融合中间件
Oracle ADF 11g
应用背景
动态创建菜单结构
点击菜单项,InlineFrame组件中动态显示菜单项对应的页面
为了说明如何灵活应用ClientListener和ServerListener,在本例子中将描述
- 静态菜单项和静态设置ClientListener和ServerListener结合应用
- 静态菜单项和动态设置ClientListener和ServerListener结合应用
- 动态菜单项和动态设置ClientListener和ServerListener结合应用
一、 静态菜单项和静态设置ClientListener和ServerListener
1,创建JSF页面,使用JDeveloper页面向导创建如下的页面
主页面RefreshInlineFrame.jspx,页面主要包括菜单条RichMenuBar和显示页面的InlineFrame组件
展现静态菜单项和静态设置ClientListener和ServerListener功能的StaticListenerMenuItem.jspx页面
展现静态菜单项和动态设置ClientListener和ServerListener功能的StaticMenuItemDynamicListener.jspx页面
展现动态菜单项和动态设置ClientListener和ServerListener功能的DynamicListenerMenuItem.jspx页面
2,添加客户端监听处理Javascript方法
为了捕捉用户点击菜单项的事件,并获得点击的是哪个菜单项,需要在页面中添加一个Javascript的方法来注册一个客户化事件,并将其添加到客户化事件队列中
1 2 3 4 5 | function clientMethodCall(event) { adfRichMenuItem = event.getSource(); AdfCustomEvent.queue(adfRichMenuItem, "customEvent",{clientId:adfRichMenuItem.getClientId()}, true); event.cancel(); } |
这个方法通过adfRichMenuItem.getClientId()获得点击的菜单项ID,并作为参数clientId返回给服务器
3,编写并注册Managed Bean:navigateBean
编写一个Managed Bean的实现类NavigateBean,其中包括一个服务器监听对应的方法来对客户端监听返回的信息进行处理,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public void handleRequest(ClientEvent event) { String clientId = (String)event.getParameters().get("clientId"); logger.info(clientId); if (clientId.equals("staticListenerMenuItem")) { setNavigateSourceURL("/faces/StaticListenerMenuItem.jspx"); } if (clientId.equals("staticMenuItemDynamicListener")) { setNavigateSourceURL("/faces/StaticMenuItemDynamicListener.jspx"); } if(clientId.equals("dynamicMenuItemAndListener")){ setNavigateSourceURL("/faces/DynamicListenerMenuItem.jspx"); } } |
方法中利用event.getParameters().get()来取得客户端监听方法中传过来参数的值,如上面就是通过clientMethodCall传过来的clientId这个参数的值,即菜单项的Id。
根据客户端传过来的参数值给InlineFrame组件设置source进而实现刷新
编写完成之后将其注册到faces-config.xml的配置文件中,并命名Managed Bean的名称为navigateBean
4,添加ClientListener和ServerListener监听
为了实现静态菜单项和静态设置ClientListener和ServerListener的功能,添加一个菜单项,并在菜单项下面添加
客户端和服务器监听,页面对应的XML代码如下:
1 |
客户端监听中指定执行的方法为上面创建好的Javascript方法clientMethodCall,类型为:action,代表当点击菜单项发出一个动作的时候触发
服务器监听中指定监听的类型,这个类型是客户端Javascript方法中添加事件队列是指定的,如上面的:customEvent;方法为Managed Bean中处理服务器监听的方法。
5,定义InlineFrame组件
往RefreshInlineFrame.jspx页面定义中添加<af:inlineFrame>组件来显示页面,代码如下:
1 |
partialTriggers:代表当触发哪些元素的时候刷新inlineFrame组件,刷新的内容来自于source参数的值。本文的例子中只要点击菜单项都需要刷新,
因此需要将菜单项的Id添加到这里,但是我们的一个菜单项是通过代码来创建的,因此这个参数的值需要动态
source:代表inlineFrame组件中显示的页面是什么,在我们的例子中,需要根据选择菜单项的不同变化为不同的页面地址和名称,因此这个参数的值也是需要动态传递的
为了实现动态传递参数的功能,我们需要利用Managed Bean的功能,添加2个私有变量,并定义它们的Accessor方法
二、静态菜单项和动态设置ClientListener和ServerListener
静态菜单项和动态设置ClientListener和ServerListener,只需要在RefreshInlineFrame.jspx页面定义中添加菜单项,不需要添加客户端和服务器监听组件。
它们通过Managed Bean动态设置,添加一个菜单项类型的私有变量,定义Accessor方法,并在其set方法中动态添加监听:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | private RichCommandMenuItem richCommandMenuItem; public void setRichCommandMenuItem(RichCommandMenuItem richCommandMenuItem) { this.richCommandMenuItem = richCommandMenuItem; if (this.richCommandMenuItem != null) { ClientListenerSet cls = new ClientListenerSet(); cls.addListener("action", "clientMethodCall"); cls.addCustomServerListener("customEvent", getClientEventMethodExpression("#{navigateBean.handleRequest}")); this.richCommandMenuItem.setClientListeners(cls); } } public MethodExpression getClientEventMethodExpression(String s) { FacesContext fc = FacesContext.getCurrentInstance(); ELContext elctx = fc.getELContext(); ExpressionFactory elFactory = fc.getApplication().getExpressionFactory(); MethodExpression methodExpr = elFactory.createMethodExpression(elctx, s, null, new Class[] { ClientEvent.class }); return methodExpr; } |
上面的代码的功能和我们在第一部分中步骤4添加监听组件是一样的,不同的只是这里通过代码动态添加。
方法完成之后需要将这个菜单项变量绑定到页面上:
1 |
三、动态菜单项和动态设置ClientListener和ServerListener
动态菜单项和动态设置ClientListener和ServerListener,要比上面两个情况稍微复杂一些
- 动态创建菜单
- 动态绑定监听
往Managed Bean的类中添加如下的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | private RichMenu dynamicRichMenu; public void createDynamicMenu(PhaseEvent phaseEvent) { RichCommandMenuItem richMenuItem = new RichCommandMenuItem(); richMenuItem.setId("dynamicMenuItemAndListener"); richMenuItem.setText("Dynamic Item and Listener"); richMenuItem.setActionExpression(getActionEventMethodExpression("dynamic")); ClientListenerSet cls = new ClientListenerSet(); cls.addListener("action", "clientMethodCall"); cls.addCustomServerListener("customEvent", getClientEventMethodExpression("#{navigateBean.handleRequest}")); richMenuItem.setClientListeners(cls); dynamicRichMenu.getChildren().add(richMenuItem); } private MethodExpression getActionEventMethodExpression(String name) { Class[] argtypes = new Class[1]; argtypes[0] = ActionEvent.class; FacesContext facesCtx = FacesContext.getCurrentInstance(); Application app = facesCtx.getApplication(); ExpressionFactory elFactory = app.getExpressionFactory(); ELContext elContext = facesCtx.getELContext(); return elFactory.createMethodExpression(elContext, name, null, argtypes); } |
修改RefreshInlineFrame.jspx的页面定义:
在页面中添加beforePhase,调用创建菜单的方法<f:view beforePhase=”#{navigateBean.createDynamicMenu}”>
将菜单项的私有变量绑定到页面中<af:menu text=”Show Listener(Dynamic Memu)” id=”dynamicMenu” binding=”#{navigateBean.dynamicRichMenu}”/>
四、运行RefreshInlineFrame.jspx页面
选择不同的菜单项,下面显示不同的内容。
五、总结
本文中利用了ClientListener和ServerListener两个监听静态和动态的配合来实现动态刷新inlineFrame的内容,本文中利用了一些常用的技巧:
- 动态创建菜单
- 动态绑定一个Action
- 动态绑定监听
- 客户端和服务器监听的应用
- 如何利用Managed Bean来动态获得需要的值
- 应用组件的partailTriggers
- af:inlineFrame组件的应用
–
