使用带有 forceSelection=false 的 ListConverter
Using ListConverter with forceSelection=false
我正在使用 <p:autocomplete>
标签和 omnifaces 转换器,以便让用户从系统中的给定地址列表中选择地址。以下是两个地址字段的示例 .xhtml 代码:
<p:autoComplete id="name" completeMethod="#{viewBean.autocompleteName}" var="_address"
value="#{viewBean.draft.address}" itemValue="#{_address}"
itemLabel="#{_address.name}">
<o:converter converterId="omnifaces.ListConverter" list="#{viewBean.addresses}" />
<p:column>
<h:outputText value="#{_address.name}" />
</p:column>
<p:column>
<h:outputText value="#{_address.street}" />
</p:column>
<p:ajax event="itemSelect" listener="#{viewBean.onAddressSelected}" update="addressPanel" />
</p:autoComplete>
<p:autoComplete id="street" completeMethod="#{viewBean.autocompleteStreet}" var="_address"
value="#{viewBean.draft.address}" itemValue="#{_address}"
itemLabel="#{_address.street}">
<o:converter converterId="omnifaces.ListConverter" list="#{viewBean.addresses}" />
<p:column>
<h:outputText value="#{_address.name}" />
</p:column>
<p:column>
<h:outputText value="#{_address.street}" />
</p:column>
<p:ajax event="itemSelect" listener="#{viewBean.onAddressSelected}" update="addressPanel" />
</p:autoComplete>
选择后,会自动填充其他字段(用于其他地址属性)。到目前为止,一切正常。
问题来了:
我想允许与选项列表中的任何现有项目不同的输入 (forceSelection="false"
)。假设用户选择了一个现有地址,但随后更改了街道名称并保存了它。
目前,使用 ListConverter,此更改会被忽略,对象保持不变。
我想要的行为是修改并保存业务对象(viewBean.draft.address
)。换句话说,新对象不再是我提供给转换器的选项列表的成员。
有没有办法在实现这种行为的同时仍然利用 omnifaces.ListConverter
的优势?还是我必须完全从头开始编写自己的转换器?
最简单的方法是将查询添加到列表中。
public List<Address> autocompleteStreet(String query) {
addresses = addressService.listByStreet(query);
addresses.add(0, new Address(query)); // <-- Just add query to list.
return addresses;
}
Update 根据评论,PF 在处理 forceSelection="false"
和转换的项目值时似乎有问题。最好的办法是如下扩展 OmniFaces ListConverter
,然后改用它。
@FacesConverter("addressListConverter")
public class AddressListConverter extends ListConverter {
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return "";
}
return ((Address) value).getStreet();
}
}
我正在使用 <p:autocomplete>
标签和 omnifaces 转换器,以便让用户从系统中的给定地址列表中选择地址。以下是两个地址字段的示例 .xhtml 代码:
<p:autoComplete id="name" completeMethod="#{viewBean.autocompleteName}" var="_address"
value="#{viewBean.draft.address}" itemValue="#{_address}"
itemLabel="#{_address.name}">
<o:converter converterId="omnifaces.ListConverter" list="#{viewBean.addresses}" />
<p:column>
<h:outputText value="#{_address.name}" />
</p:column>
<p:column>
<h:outputText value="#{_address.street}" />
</p:column>
<p:ajax event="itemSelect" listener="#{viewBean.onAddressSelected}" update="addressPanel" />
</p:autoComplete>
<p:autoComplete id="street" completeMethod="#{viewBean.autocompleteStreet}" var="_address"
value="#{viewBean.draft.address}" itemValue="#{_address}"
itemLabel="#{_address.street}">
<o:converter converterId="omnifaces.ListConverter" list="#{viewBean.addresses}" />
<p:column>
<h:outputText value="#{_address.name}" />
</p:column>
<p:column>
<h:outputText value="#{_address.street}" />
</p:column>
<p:ajax event="itemSelect" listener="#{viewBean.onAddressSelected}" update="addressPanel" />
</p:autoComplete>
选择后,会自动填充其他字段(用于其他地址属性)。到目前为止,一切正常。
问题来了:
我想允许与选项列表中的任何现有项目不同的输入 (forceSelection="false"
)。假设用户选择了一个现有地址,但随后更改了街道名称并保存了它。
目前,使用 ListConverter,此更改会被忽略,对象保持不变。
我想要的行为是修改并保存业务对象(viewBean.draft.address
)。换句话说,新对象不再是我提供给转换器的选项列表的成员。
有没有办法在实现这种行为的同时仍然利用 omnifaces.ListConverter
的优势?还是我必须完全从头开始编写自己的转换器?
最简单的方法是将查询添加到列表中。
public List<Address> autocompleteStreet(String query) {
addresses = addressService.listByStreet(query);
addresses.add(0, new Address(query)); // <-- Just add query to list.
return addresses;
}
Update 根据评论,PF 在处理 forceSelection="false"
和转换的项目值时似乎有问题。最好的办法是如下扩展 OmniFaces ListConverter
,然后改用它。
@FacesConverter("addressListConverter")
public class AddressListConverter extends ListConverter {
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return "";
}
return ((Address) value).getStreet();
}
}