Rap*_*oth 5 jsf facelets composite-component
我在我的公司"继承"了一个JSF 2(JSF 2.2.7)应用程序并面临java.lang.IllegalStateException,因为两个组件似乎具有相同的ID.
视图的结构如下(为了说明目的,我提取了相关代码,它可能包含一些拼写错误/无效语法,因为我更改了一些名称):
<p:commandButton id="editButton"
action="#{controller.prepareItem()}"
update=":itemEditDlg" oncomplete="PF('itemtEditDlg').show()" />
<comp:editItemDlg id="itemEditDlg" />
<p:dialog id="anotherDlg" >
<h:form id="anotherForm">
<c:forEach items="#{controller.allArgs}" var="arg" >
<!-- next line is the problem -->
<comp:mycomponent arg="#{arg}" />
</c:forEach>
</h:form>
</p:dialog>
Run Code Online (Sandbox Code Playgroud)
mycomponent.xhtml如下所示:
<cc:interface>
<cc:attribute name="arg" required="true" />
</cc:interface>
<cc:implementation>
<p:inputText id="argValue" value="#{cc.attrs.arg}" />
<p:message id="argValueMessage" for="argValue" />
</cc:implementation>
Run Code Online (Sandbox Code Playgroud)
重要:mycomponent组件也在editItemDlg中使用(与"anotherDlg"中的方式相同),即在对话框和forEach循环中)
如果我点击editButton,我得到:
java.lang.IllegalArgumentException: Component ID anotherForm:j_idt192:argValue
has already been found in the view.
Run Code Online (Sandbox Code Playgroud)
它相当奇怪,因为"anotherDlg"在这种情况下并不是开放的,但显然已经渲染了.
我在StackTrace中获得以下信息(仅显示相关部分):
+id: j_idt192
type: javax.faces.component.UINamingContainer@399bd0dc
+id: j_id2
type: javax.faces.component.UIPanel@24ad3910
+id: argValue <===============
type: org.primefaces.component.inputtext.InputText@687d5c3f
+id: argValueMessage
type: org.primefaces.component.message.Message@7e3361b0
+id: argValue <===============
type: org.primefaces.component.inputtext.InputText@5f52aa8a
+id: argValueMessage
type: org.primefaces.component.message.Message@2c3a7aea
Run Code Online (Sandbox Code Playgroud)
所以不知何故这些组件被渲染两次,但我无法弄清楚为什么.
我已经通过了回答,但我无法确定哪些列出的原因是我的问题.我不使用任何绑定.
到目前为止我尝试过的方法是:明确地设置id,即围绕mycomonent,将循环计数器作为ID传递给组件等,但没有成功.我认为问题无法在mycomponent中解决.我找到的唯一解决方法是制作mycomponent的物理副本,并在我的anotherForm中引用该副本(这样editItemDlg和anotherDlg不使用相同的组件).
任何帮助表示赞赏
小智 0
您不应该为组件上的输入文本分配 id。
如果您循环遍历表单上的数组,则可以肯定您的输入文本元素将被创建多次。
指定的标识符在作为最近祖先 UIComponent(NamingContainer)的后代的所有组件(包括 Facet)中必须是唯一的,或者在整个组件树的范围内(如果不存在这样的 NamingContainer 祖先)。
让我们考虑一下您的controller.allArgs列表中有两项。
您生成的输出:
<form id="anotherForm">
<input type="text" id="**argValue**">
<p:message>
<input type="text" id="**argValue**">
<p:message>
</form>
Run Code Online (Sandbox Code Playgroud)
这会导致重复的 id 异常。
您可以创建一个新的命名容器来保持input id唯一性或在添加上附加索引信息。
| 归档时间: |
|
| 查看次数: |
2310 次 |
| 最近记录: |