我正在使用JSF Primefaces 5.3在Liferay 6.2上开发一个webapp。 webapp在Tomcat上运行。 我在同一页面上有Portlet 1和Portlet 2。 我想在用户与Portlet 2中的控件交互后设置属于Portlet 1的某些后端对象的状态。
我尝试了基于事件的解决方案,效果很好。在我的view.xhtml上我有这样的东西:
<p:selectOneMenu value="#{operationBox.selected}"
valueChangeListener="#{broker.operationChanged}" onchange="submit()"
style="width:50%">
<f:selectItems value="#{operationBox.operations}" />
</p:selectOneMenu>
代理类(Portlet 2)处理操作,在ActionResponse对象中设置自定义事件,侦听器(Portlet 1)接收它。
但是,我不想提交表单,因为这会导致页面刷新,这是我不需要的。我不打算在Portlet 1中渲染任何东西。 我的经纪人类看起来就像Liferay教程和演示应用程序中提供的示例一样:
public void submit() {
logger.debug("Submitting booking changes.");
QName qName = new QName("http://liferay.com/events", "ipc.customerEdited");
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
ActionResponse actionResponse = (ActionResponse) externalContext.getResponse();
actionResponse.setEvent(qName, bookingsModelBean.getCustomer());
}
我不知道它是ajax还是selectOneMenu
标签(或两者)让我失败了:如果我执行以下操作
<f:ajax event="change" listener="#{broker.handle}"/>
我的经纪人bean得到的响应对象是ResourceResponse
,我无法转发ActionResponse
来调用setEvent(QName qname, String string)
。
selectOneMenu
是否有办法触发价值变动行动?
操作仅与提交/页面重新加载相关吗?
我需要一种方法将数据从Portlet 2发送到Portlet 1的服务器端。 在您看来,我最好的选择是什么?
非常感谢
使用最终解决方案进行编辑
事实证明,这不能通过使用当前规范的服务器端事件处理来完成。 我最终设法用客户端javascript做到了。仅当涉及的portlet位于同一页面上时,以下方法才有效: Portlet 1 - 火灾事件:
<p:selectOneMenu value="#{operationBox.selected}"
onchange="return myFireEvent('operation',this.value);>
和
<script>
function myFireEvent(caller, value) {
var payload = ...; // process your parameters
Liferay.fire('my-event-name', {
payload: payload
});
return false;
};
</script>
Portlet 2 - 接收活动:
我用来向服务器端发送数据的变通方法是通过<p:remoteCommand>
标记调用自定义js函数,必须放在<h:form>
中:
<p:remoteCommand name="handleEvent" actionListener="#{icpReceiver.handleEventJS}"/>
这是由Liferay API提供的js接收器函数调用的:
<script>
Liferay.on('my-event-name', function(event) {
handleEvent([{name:'payload', value:event.payload}]);
});
</script>
这就是全部。
答案 0 :(得分:1)
你是对的 - JSR-286-portlet间通信只涉及动作(和事件)阶段,既不在渲染也不在资源阶段。该规范刚刚出现有点太早,无法想象这一点。
您仍然可以使用基于Ajax的IPC,但您必须自己完成此操作 - 通常在前端,例如通过一个页面上的portlet之间的Javascript通信。它不会是JSR-286-IPC。
相关主题(但对手头的具体情况不太有帮助)可能是Liferay的SPA(单页应用程序),您不再需要完整页面重新加载 - 而是门户网站进程并传输portlet的delta状态,同时仍然构建经典portlet。