2

Composite Componentこんにちは私が書いたを使用しているこのWierdの問題があり、CCのバッキングBean( componentTypeBean)の以前の使用から値を取得します

コードを表示するよりも、これをうまく説明する方法がわかりません。私はそれについて簡単に説明し、冗長な部分をカットしようとします:これはComposite Component定義です:

<cc:interface componentType="dynamicFieldGroupList">
   <cc:attribute name="coupletClass" />
   <cc:attribute name="form" default="@form"/>
   <cc:attribute name="list" type="java.util.List" required="true"/>
   <cc:attribute name="fieldNames" type="java.util.List" required="true" />
</cc:interface>

<cc:implementation>
    <h:dataTable value="#{cc.model}" var="currLine">
        <h:column>
            <h:outputText id="inner_control_component" value="Inner Look at currLine:#{currLine}"/>
        </h:column>
    </h:dataTable>
</cc:implementation>

CC Beanの定義:

@FacesComponent(value = "dynamicFieldGroupList")
// To be specified in componentType attribute.
@SuppressWarnings({ "rawtypes", "unchecked" })
// We don't care about the actual model item type anyway.
public class DynamicFieldGroupList extends UIComponentBase implements
        NamingContainer
{

    private transient DataModel model;

    @Override
    public String getFamily()
    {
        return "javax.faces.NamingContainer"; // Important! Required for
                                                // composite components.
    }

    public DataModel getModel()
    {
        if (model == null)
        {
            model = new ListDataModel(getList());
        }

        return model;
    }

    private List<Map<String, String>> getList()
    { // Don't make this method public! Ends otherwise in an infinite loop
        // calling itself everytime.
        return (List) getAttributes().get("list");
    }

}

そして使用コード:

<ui:repeat var="group" value="#{currentContact.detailGroups}">
    <h:panelGroup rendered="#{not empty group.values}">
        <h:outputText id="controlMsg" value=" list:#{group.values}" /><br/><br/>
        <utils:fieldTypeGroupList list="#{group.values}"
            fieldNames="#{group.fields}" coupletClass="utils" />
    </h:panelGroup>
</ui:repeat>

idのテキストにcontrolMsgは正しい値が表示され、#{group.values}idのコンポーネント内のコントロール出力にinner_control_componentは以前の使用からの値が表示されます。

値は最初は正しいです...

CC Beanの使用における根本的なエラーだと思います。そうでない場合は、MyFaces 2.1(私が使用している)のバグである可能性があります。

4

2 に答える 2

6

この動作の説明は簡単です。ビューで定義されているコンポーネントは1つだけです。したがって、1つのモデルを持つバッキングコンポーネントも1つだけです。モデルは最初のgetで遅延ロードされるため、同じモデルが親の反復コンポーネントのすべての反復で再利用されます。

<ui:repeat>、ビューのビルド時(JSTLのように)ではなく、ビューのレンダリング時に実行されます。したがって、ビューには、によって繰り返されるアイテムほど多くのコンポーネントは物理的にありません<ui:repeat><c:forEach>(またはビューのビルド時に実行される他の反復タグ)を使用している場合、複合コンポーネントは期待どおりに動作します。

データモデルがバッキングコンポーネントに保持される方法を変更したいとします。親の反復コンポーネントの反復ごとに個別のデータモデルを保持したいとします。方法の1つは、model次のようにプロパティを置き換えることです。

private Map<String, DataModel> models = new HashMap<String, DataModel>();

public DataModel getModel() {
    DataModel model = models.get(getClientId());
    if (model == null) {
        model = models.put(getClientId(), new ListDataModel(getList()));
    }
    return model;
}

参照:

于 2011-06-27T06:11:53.063 に答える
3

ここで説明する問題は、複合コンポーネントの使用によって隠された、JSFの古い既知の問題です。これは非常に重要で難しいため、代わりにここで回答します。これについては、ブログエントリに詳細な回答を作成します。データテーブルの行ごとのJSFコンポーネントの状態

この答えを短くするために、MyFaces2.1のバグではないと言います。2.1.1を使用してください。これは、2.1.0のクイックバグ修正バージョンです。JSF 2.1には、rowStatePreservedと呼ばれるh:dataTableの新しいプロパティがあります。このシナリオは、「この小さな赤ちゃん」が役立つ1つのケースにすぎません。ui:repeatをh:dataTableに置き換え、rowStatePreserved="true"を追加するだけです。それでうまくいきます。モデルを操作する(行を追加または削除する)必要がある場合は、tomahawk t:dataTableおよびt:dataListを使用できますが、今のところスナップショットバージョンを取得する必要があります。これは、現時点では別のJSFフレームワークでは利用できない新しいものであることに注意してください(2011年6月)。

さらに詳しい情報が必要な場合は、TwitterでMyFacesチームに注目するか、 MyFacesユーザーとDevメーリングリストの専門家に質問してください。

于 2011-06-26T20:33:58.123 に答える