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用户和开发人员邮件列表上的专家咨询。