PrimeFaces:将选定的值传递给自动编译方法(请求范围)

问题描述 投票:0回答:1

我有一个目前不易实施的要求。应根据

SelectOneMenu
选择在此处预先选择自动完成功能。为此,我需要之前在
completeMethod
中选择的值。 一般来说,从completeMethod返回的列表应该按所选值进行过滤。

我尝试使用

f:attribute
解决问题。不幸的是,这里的值始终为 null,因为我使用的是请求范围的 bean。

这是我当前尝试的代码:

查看:

      <h:form id="myForm">
            <h:outputLabel value="My Selection" for="selectFldId" />
            <p:selectOneMenu
                value="#{autocompleteWithPreSelectionBean.selectedValue}"
                id="selectFldId">
                <f:selectItem itemLabel="Select One" itemValue=""
                    noSelectionOption="true" />
                <f:selectItems
                    value="#{autocompleteWithPreSelectionBean.selectItems}" />
                <p:ajax event="change" update="autoCompleteId" process="@this" />
            </p:selectOneMenu>


            <p:autoComplete
                disabled="#{empty autocompleteWithPreSelectionBean.selectedValue}"
                value="#{autocompleteWithPreSelectionBean.completedText}"
                id="autoCompleteId"
                completeMethod="#{autocompleteWithPreSelectionBean.completeText}">
                <f:attribute name="filter"
                    value="#{autocompleteWithPreSelectionBean.selectedValue}" />
            </p:autoComplete>
    </h:form>

豆:

@Named(value = "autocompleteWithPreSelectionBean")
@RequestScoped
public class AutocompleteWithPreSelectionBean implements Serializable {
    private List<SelectItem> selectItems;
    private String selectedValue;
    private String completedText;

    @PostConstruct
    public void init() {
        selectItems = new ArrayList<>();
        selectItems.add(new SelectItem("ID1", "Value 1"));
        selectItems.add(new SelectItem("ID2", "Value 2"));
        selectItems.add(new SelectItem("ID3", "Value 3"));
        selectItems.add(new SelectItem("ID4", "Value 4"));
        selectItems.add(new SelectItem("ID5", "Value 5"));
    }

    public List<String> completeText(String query) {

        String filterValue = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes()
                .get("filter");
        
        //selectedValue is null
        //filterValue is null
       ... 
       }
...
}

是否有一个解决方案可以满足我的要求,让我可以继续使用请求范围的 bean?也欢迎其他方法或解决方案。

我正在使用 Faces 4 和 PrimeFaces 13。

jsf primefaces
1个回答
0
投票

有两个因素导致了可观察到的问题。

disabled
属性也会在“应用请求值”阶段进行评估。

<p:autoComplete ... disabled="#{empty autocompleteWithPreSelectionBean.selectedValue}">

但是,在请求作用域 bean 的情况下,这将always 评估

true
,因为
selectedValue
已被清除,并且仅在更新模型值阶段设置。这是“应用请求值”阶段“之后”。因此,这永远无法评估 false,因此自动完成组件在应用请求值阶段基本上永久禁用。
解决此问题的一种方法是让它检查与下拉组件关联的请求参数,而不是与下拉组件关联的模型值。

<p:selectOneMenu ... binding="#{selectFld}" /> <p:autoComplete ... disabled="#{empty param[selectFld.clientId += '_input']}" />

如果您使用 PrimeFaces 
Partial Submit

功能,那么只有当您将以下 <p:ajax> 添加到自动完成组件时才会起作用,该组件明确指示 ajax 也发送下拉组件的提交值:

<p:autoComplete ...>
    <p:ajax event="query" process="@this selectFldId" update="@this" />
</p:autoComplete>

其次,为了让与下拉组件关联的 bean 属性已经在自动完成方法中预先填充,我希望前面演示的 
<p:ajax>

足以完成任务:

public List<String> completeText(String query) {
    System.out.println(selectedValue); // Should already be populated.
    // ...
}

然而,我惊讶地发现这仍然是
null

。然后我进行了一些调试,更惊讶地发现完整的方法是在“应用请求值”阶段而不是预期的“调用应用程序”阶段调用的!我不确定这是不是故意的。

所以我们能做的最好的事情就是继续 

<f:attribute>

技巧,但这次重用

disabled
属性中使用的请求参数映射技巧:
<p:autoComplete ...>
    <f:attribute name="filter" value="#{param[selectFld.clientId += '_input']}" />
</p:autoComplete>

public List<String> completeText(String query) {
    String filterValue = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes().get("filter");
    // ...
}

与具体问题无关

,这里没有正确理解noSelectionOption="true"。在你的上下文中它基本上被完全忽略了。请改用

itemValue="#{null}"
。另请参阅
在 JSF 中向 selectOneMenu 添加“未选择任何内容”选项的最佳方法

© www.soinside.com 2019 - 2024. All rights reserved.