当用户选择选项列表目标列表中的项目时,我想重新渲染组件。
我该怎么做?
<小时/>更新(2013 年 12 月 17 日)
我在这里描述了此问题的完整解决方案 - http://leonotepad.blogspot.com.br/2013/12/primefaces-capturing-target-list-item.html
谢谢@Hatem,如果没有你的回答,我无法解决这个问题。
基本上是这样的:
我有一个 @ViewScoped 托管 bean,其中的 p:pickList 通过 p:selectMany 组件使用 p:ajax 更新事件进行过滤。
像这样
<p:outputLabel for="siteFilter" value="Site Filter:" style="width:100px;"/>
<p:selectOneMenu converter="#{siteTypeConverter}" id="siteFilter" value="#{myMB.selectedSiteType}" style="width:200px;">
<f:selectItem itemLabel="Select Site Type" itemValue="#{null}" />
<f:selectItems value="#{myMB.siteTypeFilterList}" var="st" itemLabel="#{st.name}" itemValue="#{st}" />
<p:ajax update="sites" listener="#{myMB.handleSiteTypeFilterChange}" oncomplete="rebindClicks()"/>
</p:selectOneMenu>
<p:outputLabel for="sites" value="Sites:" style="width:100px;"/>
<p:pickList
widgetVar="xyzabc"
id="sites"
value="#{myMB.sites}"
var="site"
converter="#{siteConverter}"
itemLabel="#{site.siteType.name}.#{site.name}"
itemValue="#{site}" />
这里的想法是当用户单击某个 pickList 目标列表项时触发一个新事件。
因此,按照@Hatem 的建议,我们必须将单击事件绑定(bind)到每个目标元素。像这样
(...)
<p:remoteCommand name="updateCommand" action="#{myMB.updateAccounts}" update="accounts"/>
</h:form>
<h:outputScript library="js" name="pickListHack.js" />
(...)
请注意,我必须在表单之后添加它。
pickListHack.js 位于 WebContent/resources/js/pickListHack.js
function rebindClicks() {
xyzabc.jq.on('click','.ui-picklist-target li',function(){
var item = $(this).attr('data-item-value');
alert(item);
updateCommand([{name:'param', value:item}]);
});
};
$(document).ready(function() {
rebindClicks();
});
这里的技巧似乎是,在更新事件之后,绑定(bind)丢失,因此我们必须在更新后重新绑定(bind)它们。这就是为什么 p:ajax 有 oncomplete 事件。
最后,当用户单击目标列表中的元素时,我们调用通过 p:remoteCommand 声明的 updateCommand。
请注意,所选项目作为名为“param”的参数传递。我们将此参数返回到托管 bean 中,如下所示
public void updateAccounts(){
String value = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("param");
System.out.println(">"+value);
this.accounts = value;
}
在本例中,该值只是 ID,因为这就是我的 siteConverter 对对象执行的操作。
@ManagedBean
@RequestScoped
public class SiteConverter implements Converter,Serializable{
private static final long serialVersionUID = -194442504109002565L;
@EJB
private MyEJB myEJB;
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2)
throws ConverterException {
if (arg2 != null){
Site s = myEJB.getSiteById(Long.parseLong(arg2));
return s;
}else{
return null;
}
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2)
throws ConverterException {
if (arg2 != null){
Site s = (Site)arg2;
return String.valueOf(s.getId());
}else{
return null;
}
}
}
最佳答案
这样应该就可以了。
远程命令
<p:remoteCommand name="updateCommand" update="componentId" />
p:pickList
<p:pickList id="pickList" widgetVar="pickListVar" value="#{pickListBean.cities}"
var="city" itemLabel="#{city}" itemValue="#{city}" />
JS
$(document).ready(function() {
PF('pickListVar').jq.on('click','.ui-picklist-target li',function(){
updateCommand();//remoteCommand to update
//and you can get the item value and lable
$(this).attr('data-item-value');
$(this).attr('data-item-lable');
});
});
编辑:
如果你的 pickList 被另一个组件定期更新,你最终会丢失点击事件。
在这种情况下,您可能希望绑定(bind)对 pickList 的父容器组件的点击。
例如:
$('#formId').on('click','.ui-picklist-target li',function(){
updateCommand();//remoteCommand to update
//and you can get the item value and lable
$(this).attr('data-item-value');
$(this).attr('data-item-lable');
});
但是,如果任何其他组件更新了整个表单,您将丢失事件绑定(bind)。
关于java - Primefaces p :picklist - how I capture the event of selecting an item in the target list?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20618608/