使用带有 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();
    }

}