Ajax 使用自定义组件并获取javax.faces.FacesException:java.io.IOException:无法添加同一组件两次
我正在开发一个旧的系统,它有很多以前使用jsf1.2编写的代码。现在我的任务是在单击按钮时通过ajax动态添加/删除一组输入元素 在如何动态添加输入字段的指导下,我做了一些小的调整来支持ajax,并证明了概念的正确性。 现在问题发生在,而不是Ajax 使用自定义组件并获取javax.faces.FacesException:java.io.IOException:无法添加同一组件两次,ajax,jsf,tags,facelets,Ajax,Jsf,Tags,Facelets,我正在开发一个旧的系统,它有很多以前使用jsf1.2编写的代码。现在我的任务是在单击按钮时通过ajax动态添加/删除一组输入元素 在如何动态添加输入字段的指导下,我做了一些小的调整来支持ajax,并证明了概念的正确性。 现在问题发生在,而不是或其他表单字段我使用我们自己的自定义标记组件 当使用自定义标记时,我会在页面加载时显示页面,但是如果我尝试删除一个项目,对于列表中的第一个组件,我会得到错误java.io.IOException:无法添加相同的组件两次:editform:parentTabl
代码>或其他表单字段我使用我们自己的自定义标记组件
当使用自定义标记时,我会在页面加载时显示页面,但是如果我尝试删除一个项目,对于列表中的第一个组件,我会得到错误java.io.IOException:无法添加相同的组件两次:editform:parentTable:0:fieldsTable:0:HTML\u TITLE\u INPUT\u en
我相信问题是由于当自定义标记尝试在回发时再次添加组件时,组件已经在组件树中,但我仍然不知道如何修复该问题
注1:我必须使用我们的自定义标记,因为它内部有很多逻辑,用于显示每种类型的表单字段(inputText、textarea、复选框等)
xhtml代码:
<h:dataTable id="parentTable" value="#{bean.groups}" var="group" styleClass="parentTableStyleClass">
<h:column>
<h:dataTable id="fieldsTable" value="#{group.fields}" var="field">
<h:column>
<h:outputLabel value="#{field.label}" styleClass="col-sm-2 control-label" />
</h:column>
<h:column>
<customTag:propertyValue
name="#{field.name}"
operation="edit"
instance="#{bean.instance}"
styleClass="form-control"
inputWrapperClass="col-sm-5"/>
</h:column>
</h:dataTable>
</h:column>
<h:column>
<p:commandButton value="Remove Group"
styleClass="btn btn-secondary btn-sm"
action="#{bean.removeGroup(group)}"
process="@(.parentTableStyleClass)"
update="@(.parentTableStyleClass)" />
</h:column>
</h:dataTable>
你解决了这个问题吗?@PhellipeKelbert是的,我解决了,但我认为我的解决方案不正确,因为它看起来太粗糙了。我使用的不是h:dataTable,而是jstl的c:foreach,每当我需要条件呈现时,我都使用c:if(否则我会得到‘不能添加相同的组件’)和components-rendered标记(否则我会在ajax更新后得到相同的组件两次)。最后一件事是在我的ViewScope bean中添加一个int值,该值在每次ajax请求时递增,然后作为标记属性转发到组件标记,并用于始终生成一个新的唯一ID(intValue+componentName)
public void encodeBegin(FacesContext context) throws IOException {
getChildren().clear();
...
// bunch of logic
...
HtmlPanelGroup wrapper = new HtmlPanelGroup();
HtmlInputText inputText = new HtmlInputText();
...
// bunch of code creating input text field
...
wrapper.setStyleClass(getInputWrapperClass() + " input-group");
wrapper.getChildren().add(inputText);
getChildren().add(wrapper);
}