3

动态实例化 PF 3.4.2 AutoComplete 组件时出现问题。组件最初呈现正常,其值在部分处理时刷新, 但从不显示建议。

我正在通过以下方式实例化此控件:

    AutoComplete ac = (AutoComplete) context.getApplication().createComponent(AutoComplete.COMPONENT_TYPE);
    final String varName = "p";

    ValueExpression ve = JSFUtils.createValueExpression("#{minContext.selected.sen}"), Sen.Type);
    ac.setValueExpression("value", ve);

    ac.setForceSelection(true);

    ac.setVar(varName);

    ValueExpression itemLabel = JSFUtils.createValueExpression("#{sc:senLibelle(p)}"), String.class);
    ac.setValueExpression("itemLabel", itemLabel);

    ValueExpression itemValue = JSFUtils.createValueExpression("#{" + varName + "}");
    ac.setValueExpression("itemValue", itemValue);

    MethodExpression completeMethod = JSFUtils.createMethodExpression("#{senUtils.completeAllSens}", List.class,new Class[]{String.class});
    ac.setCompleteMethod(completeMethod);

然后使用将其添加到父控件

    getChildrens().add(ac);

父组件是 PF PanelGrid 的派生。我成功地使用这种方法来生成各种版本面板,它就像一个魅力。但我不明白为什么它没有自动完成。

父控件如下所示:

@FacesComponent(SenatDataTableEntryDetail.SENAT_COMPONENT_TYPE)
public class SenatDataTableEntryDetail extends PanelGrid {

    /** Leaving renderer unchanged, so that PF renderer for PanelGrid is used.
     */
    public static final String SENAT_COMPONENT_FAMILY = "fr.senat.faces.components";
    public static final String SENAT_COMPONENT_TYPE = SENAT_COMPONENT_FAMILY + ".SenatDataTableEntryDetail";

    private enum PropertyKeys { mapper, bean; }

    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        super.encodeBegin(context);
        addDynamicChildren(context);
    }

    @Override
    public boolean getRendersChildren()
    {
        return true;
    }

    ...

    private Boolean isInitialized() {
        return (Boolean)getStateHelper().eval(SENAT_INITIALIZED,false);
    }

    private void setInitialized(Boolean param) {
        getStateHelper().put(SENAT_INITIALIZED, param);
    }

    private void addDynamicChildren(FacesContext context)  throws IOException {
        if(isInitialized()) {
            return;
        }
        setInitialized(true);
        /* components are instiated and added as children only once */
    }    
}

它只是将孩子添加到面板网格中。

自定义组件声明的其他方面(在 taglib 等中)都可以。

问题似乎不在于 EL 表达式、completeMethod 定义等。如果我在我的测试 xhtml 页面中包含具有相同参数的 p:autoComplete 实例,它会按预期工作:

    <p:autoComplete value="#{minContext.selected.sen}" forceSelection="true" 
                        var="p" itemLabel="#{sc:senLibelle(p)}" itemValue="#{p}"
                        completeMethod="#{senUtils.completeAllSens}"/>

我注意到 PF AutoComplete 组件有点特殊,因为它在检测到查询时呈现不同。请参阅http://primefaces.googlecode.com/files/primefaces-3.4.2.zip中的 AutoCompleteRenderer 源代码。

在“动态实例化”的情况下,不调用该组件的解码方法。我没有找到最后几天的原因,但没有成功。

我期待您就如何检查以纠正这个烦人的“错误”提出建议。

4

1 回答 1

2

所以,问题出在 id 生成中(见两条评论)。

组件实例化的开始变为:

AutoComplete ac = (AutoComplete) context.getApplication().createComponent(AutoComplete.COMPONENT_TYPE);
ac.setParent(this);
ac.setId(...some application specific unique id generation...);

final String varName = "p";

通过这种方式,命名容器在客户端 ID 生成中得到了适当的考虑。

于 2013-01-22T09:44:11.497 回答