每次使用时都会在复合组件中获取相同的“componentType”实例



Hi Have this Wierd Issue,其中我正在使用我编写的Composite Component,并且我从以前使用CC(componentType bean)的backing bean中获得值

我不知道如何更好地描述这一点,而不仅仅是展示代码。我会尽量简要介绍一下,并去掉多余的部分:这是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组件内部的控制输出显示以前使用的值。

值第一次是正确的。。。

我想这是使用CCbean时的一个基本错误,否则它可能是MyFaces 2.1(我正在使用)的一个错误

这种行为的解释很简单:视图中只定义了一个组件。因此,对于一个模型,也只有一个支持组件。由于模型是在第一次获取时延迟加载的,因此在父迭代组件的每次迭代中都会重用相同的模型。

<ui:repeat>不会像JSTL那样在视图构建期间运行,而是在视图渲染期间运行。因此,视图中的组件在物理上不如<ui:repeat>迭代的项那么多。如果您使用<c:forEach>(或在视图构建期间运行的任何其他迭代标记),那么复合组件的行为将如您所期望的那样。

您希望更改数据模型在后台组件中的保存方式。您希望为父迭代组件的每次迭代保留一个单独的数据模型。其中一种方法是如下替换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;
}

另请参阅:

  • 什么';视图构建时间是多少

这里描述的问题是JSF中一个旧的已知isse,它被复合组件的使用所隐藏。这是如此重要和困难,因此我在这里的一个博客条目中创建了一个详细的答案:数据表的每行JSF组件状态

简而言之,我要告诉你这不是MyFaces2.1中的一个bug。请使用2.1.1,因为这是2.1.0的快速错误修复版本。在JSF 2.1中,h:dataTable有一个新的属性,名为rowStatePreserved,这个场景只是"这个小婴儿"变得有用的一个例子。只需将ui:repeat替换为h:dataTable,然后添加rowStatePreserved="true"。那就行了。如果您需要操作模型(添加或删除行),您可以使用tomahawk t:dataTable和t:dataList,但现在您必须使用快照版本。请注意,这是目前在任何不同的JSF框架中都不可用的新东西(2011年6月)。

如果你需要更多信息,请在推特上与MyFaces团队保持联系,或向MyFaces用户和开发人员邮件列表上的专家咨询。

相关内容

  • 没有找到相关文章

最新更新