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 の派生です。私はこのアプローチをうまく使ってさまざまなエディションのパネルを生成しており、魅力的に機能します。しかし、autoComplete を使用しない理由がわかりません。

親コントロールは次のようになります。

@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の生成にありました(2つのコメントを参照)。

コンポーネントのインスタンス化の開始は次のようになります。

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 に答える