首先,我使用的是Primefaces 5.1和JSF 2.2.2。
问题
我正在创建一个拥有200多个OneMenus的网站(这不是我的决定......)。有一个包含选项的列表,每个OneMenu都在使用它。
使用"静态"方式导致所有探险者挂起甚至崩溃。
<h:selectOneMenu value="#{day.movieEvaluatorName}" styleClass="comboboxMitarbeiter">
<f:selectItems value="#{comboListsBean.staffMembers}" var="member" itemValue="#{member.name}" itemLabel="#{member.fullName}" />
<p:ajax listener="#{...save()}" />
</h:selectOneMenu>
现在因为选项列表总是一样的我认为&#34;让我们使用一些jQuery并在有人点击一个时填写选项。
<h:selectOneMenu value="#{day.movieTechnicanName}" styleClass="comboboxMitarbeiter">
<f:selectItem itemValue="#{day.movieTechnicanName}" itemLabel="#{day.movieTechnican}" />
<p:ajax listener="#{...save()}" />
</h:selectOneMenu>
JS
var comboboxOption = {
<c:forEach items="#{comboListsBean.staffMembers}" var="member">
'#{member.name}' : '#{member.fullName}',
</c:forEach>
};
var _select = $('<select>');
$.each(comboboxOption, function(val, text) {
_select.append($('<option></option>').val(val).html(text));
});
$(document).ready(function() {
$( ".comboboxMitarbeiter" ).focus(function() {
$(this).append(_select.html());
});
});
现在&#34;填充&#34;工作得非常好但是当我尝试更改其中一个OneMenus JSF的值时,会对OneMenu进行一些验证,告诉我该值无效且&#34; ... save()&#34;函数永远不会被调用。
问题
如何在OneMenu上禁用验证?我已经尝试过&#34; required = false&#34;但这没有用。或者还有其他方法可以提高性能吗?
顺便说一句,我已经在primefaces论坛上发布了这个,但因为这是一个JSF问题,我不想在那里得到答案。 http://forum.primefaces.org/viewtopic.php?f=3&t=40288&e=0
答案 0 :(得分:2)
问题是,这不适用于JSF的设计方式。在Apply request values
阶段,JSF将恢复组件树以更新每个组件的值。到目前为止,SelectOneMenu
的 listSource 为空。因此,JSF无法将您的(生成javascript)值绑定到组件,因为它不在listSource中,这是SelectOneMenu的要求。
这不是您可以禁用的典型验证。 SelectOneMenu
的合同,每个有效选择都需要在其元素集合中。
如果您想使用Javascript填充SelectOneMenu
,则应使用jsf&#39; ish方法来实现此目的。只有这样,后端上的相应组件才会知道您的选择选项,然后只有SelectOneMenu
的值才有效。
使用空列表和SelectOneMenu
选项呈现noSelectionOption
个。每当用户悬停selectOneMenu
时,添加一个在您的辅助bean上调用方法的ajax侦听器。此方法应将所需元素添加到listsource,最后update
selectOneMenu
,以显示填充值。
一个简单的例子如下:
@Named
@ViewScoped
public class TestController implements Serializable {
private List<String> options = new LinkedList<String>();
private String selectedOption;
public void populateList(AjaxBehaviorEvent event) {
this.options.add("foo");
this.options.add("bar");
this.options.add("baz");
}
public void save() {
System.out.println(this.selectedOption);
}
//+getter and setter
}
在ui部分,你只需要注意不要一遍又一遍地召唤听众。
当用户悬停select时,以下示例将加载元素,因此ajax事件将被禁用。现在可以使用SelectOneMenu
,就像它从头开始填充一样。
<h:form>
<h:selectOneMenu value="#{testController.selectedOption}" id="myList">
<f:selectItem itemValue="" noSelectionOption="true" itemLabel="Please select something."/>
<f:selectItems value="#{testController.options}" var="item" itemLabel="#{item}" />
<p:ajax event="mouseover" listener="#{testController.populateList}" update="@this" disabled="#{not empty testController.options}" />
</h:selectOneMenu>
<p:commandButton action="#{testController.save()}"></p:commandButton>
</h:form>