我刚开始在Liferay(6.2(中进行开发。我们正在为客户制作一个门户,我们正在使用 JSF 和素数。
核心功能运行良好。但现在我有点卡住了。我们有一些页面,客户可以在其中查看购买的商品和其他东西。效果也很棒。
但是不,我想从项目(详细信息(转到另一个页面并将itemnumber
作为参数。
- 用户转到第一页(他购买的所有物品(
- 单击详细信息 ->显示此项目的详细信息。在这里,我想链接到"消息"。
- 现在用户在"消息"页面上,过滤器设置为
itemnumber
.
Portlet 仅由我们插入(不是客户 - 它们只有"只读"访问权限(
这甚至是解决这个问题的正确方法吗?如何实施?
项目的要求,是否;
1. 您希望保持在同一页面上以在pop_up或
上显示项目详细信息2. 您希望导航到不同的页面承载请求参数,并根据该参数值过滤某些数据并显示详细信息。
如果遵循第一种方法,则可以在数据表或网格中放置每个项目的详细信息链接,并带有唯一的item_number
。将此链接绑定到 Bean 的方法 (actionListener(,并根据从操作中提取item_number
填充项目详细信息。
或者,如果您遵循第二种方法,则只需将详细信息页面的链接(从 Portlet 的首选项中是静态的或动态的(绑定到超链接queryString
,例如/details?item_number=x
x
是唯一item_number
的超链接。在详细信息页面(删除详细信息 Portlet 的位置(上,从请求中提取该参数并填充项目详细信息。
满足您的要求,这两种方法都很好。但是,避免重定向会很好。
更新:
添加您在项目 portlet 中dataTable
的以下链接:
<h:outputLink target="_blank" value="/group/pages/message">
Go to Messages
<f:param name="item_number" value="#{item.itemNumber}" />
</h:outputLink>
其中/group/pages/message
是页面的URL,item.itemNumber
是item
在dataTable
中的动态值。
将以下代码添加到消息 Bean 的构造函数中:
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
PortletRequest portletRequest = (PortletRequest) externalContext.getRequest();
HttpServletRequest httpServletRequest =
PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(portletRequest));
int itemNumber = ParamUtil.getInteger(httpServletRequest, "item_number", 0);
if (itemNumber > 0) {
// Filter messages here based on itemNumber
}
由于您的facelet(JSF视图(位于不同的Portlet中,因此您需要执行Inter Portlet Communication (IPC)
。
使用组件会话的工控机
可以将 IPC 基于组件会话,以便将itemnumber
传递到messages
组件。要执行此操作,请在发送方组件中获取会话组件,如下所示
PortletSession portletSession = renderRequest.getPortletSession();
portletSession.setAttribute("key", value ,PortletSession.APPLICATION_SCOPE);
并在接收器组件中
PortletSession portletSession = renderRequest.getPortletSession();
String value = (String) portletSession.getAttribute("key ",PortletSession.APPLICATION_SCOPE);
// Do what ever you want...
在这两个组件中,在liferay-portlet.xml
文件中添加以下属性
private-session-attributes>false</private-session-attributes>
使用公共渲染参数的 IPC
将itemnumber
传递给 Portlet messages
的另一种方法是使用 public render parameters
。为此,您需要定义一个公共渲染参数
<portlet-app ...>
...
<public-render-parameter>
<identifier>identifier</identifier>
<qname xmlns:x="http://namespace.com">x:identifier</qname>
</public-render-parameter>
...
</portlet-app>
并在两个组件中声明它,如下所示
<portlet>
...
<supported-public-render-parameter>identifier</supported-public-render-parameter>
...
<portlet>
然后,您可以按如下方式发送itemnumber
actionReponse.setRenderParameter("identifier", value);
并检索它
renderRequest.getParameter("identifier");
// Do what ever you want...
使用事件进行工控
通过itemnumber
的最后一种方法是使用 event
.由于您使用JSF
作为 Portlet 框架,因此 Portlet 之间的事件是完全不同的。您必须执行以下步骤:
1. 定义您的活动
在portlet.xml
文件中定义事件
<event-definition xmlns:event="http://www.namespace.com">
<qname>identifier</qname>
<value-type>java.lang.String</value-type>
</event-definition>
2. 创建事件桥处理程序
创建一个实现BridgeEventHandler
的类,如下所示
public class CustomBridgeEventHandler implements BridgeEventHandler {
@Override
public EventNavigationResult handleEvent(FacesContext facesContext, Event event) {
EventNavigationResult eventNavigationResult = null;
// Processing the event will be written here...
return eventNavigationResult;
}
}
3. 发送方组件在发送方 portlet 中,需要在portlet.xml
文件中声明事件和桥接处理程序。
事件
<portlet>
...
<supported-publishing-event xmlns:event="http://www.namespace.com">
<qname>identifier</qname>
</supported-publishing-event>
...
</portlet>
桥
<portlet>
...
<init-param>
<name>javax.portlet.faces.bridgeEventHandler</name>
<value>com.roufid.tutorials.bridge.CustomBridgeEventHandler</value>
</init-param>
...
</portlet>
触发事件
public void yourMethod() {
// Getting the faces context.
FacesContext fc = FacesContext.getCurrentInstance();
// Getting the portlet action response.
ActionResponse actionReponse = (ActionResponse) fc.getExternalContext().getResponse();
// Firing the event
QName qName = new QName("http://www.namespace.com ", "identifier");
actionReponse.setEvent(qName, dataYouWantToSend);
}
4. 接收组件在接收方 portlet 中,需要在 portlet.xml
文件中声明事件和桥接处理程序。
事件
<portlet>
...
<supported-publishing-event xmlns:event="http://www.namespace.com">
<qname>identifier</qname>
</supported-publishing-event>
...
</portlet>
桥
<portlet>
...
<init-param>
<name>javax.portlet.faces.bridgeEventHandler</name>
<value>com.roufid.tutorials.bridge.CustomBridgeEventHandler</value>
</init-param>
...
</portlet>
在网桥处理程序中处理事件
public class CustomBridgeEventHandler implements BridgeEventHandler {
@Override
public EventNavigationResult handleEvent(FacesContext facesContext, Event event) {
EventNavigationResult eventNavigationResult = null;
String eventQName = event.getQName().toString();
// Processing the defined event.
if (eventQName.equals("{http://www.namespace.com}identifier")) {
// Getting the event value.
String value = (String) event.getValue();
// Do what ever you want here...
}
return eventNavigationResult;
}
}
在所有情况下,由于您的 Portlet 处于不同的战争中,因此您需要portlet-ext.properties
文件中添加此属性,以允许位于不同 Liferay 页面的 Portlet 之间进行 IPC
portlet.public.render.parameter.distribution=layout-set
更多信息和示例
- 使用会话的 IPC | 示例
- 使用公共渲染参数的 IPC | 示例
- 使用事件进行工控机|示例