复合组件中action属性targets绑定动态ID的实现方案求助
解决JSF复合组件动态ID下的action绑定问题
嘿,我明白你遇到的问题了——targets属性确实没法直接用动态ID,这是因为它的工作时机和动态EL解析的时机不匹配。
为什么动态ID在targets里失效?
composite:attribute的targets属性是在组件树构建的早期阶段处理的,这时候#{cc.attrs.tempId}这种动态表达式还没被解析成具体的字符串,JSF根本找不到你要绑定的那个动态ID的内部按钮,自然就绑定失败了。
两种可行的解决方案
方案一:直接绑定属性(推荐,最简单)
其实你现在的代码已经走在正确的路上了!内部的<p:commandButton>直接写action="#{cc.attrs.action}",这就已经把外部传入的action表达式完美传递给按钮了,完全不需要targets属性。
修改后的复合组件代码:
<composite:interface componentType="myCC"> <composite:attribute name="tempId" required="false"/> <composite:attribute name="action" required="false"/> <!-- 删掉targets即可 --> </composite:interface> <composite:implementation> <p:commandButton id="#{cc.attrs.tempId}button" action="#{cc.attrs.action}"/> </composite:implementation>
这样外部使用时,不管你传的tempId是什么动态值,action都会正确绑定到内部按钮,完全能满足你的需求。
方案二:给内部组件固定ID(如果一定要用targets)
如果你坚持要使用targets属性,那得给内部按钮一个固定的静态ID,因为targets只能识别静态的组件ID。比如:
<composite:interface componentType="myCC"> <composite:attribute name="tempId" required="false"/> <composite:attribute name="action" targets="innerBtn" required="false"/> <!-- 指向固定ID --> </composite:interface> <composite:implementation> <p:commandButton id="innerBtn" action="#{cc.attrs.action}"/> </composite:implementation>
不过这种方式下,按钮的客户端ID会变成fooid1:innerBtn(对应第一个实例),而不是你原来想要的inFirstSpanbutton。如果必须保留动态客户端ID,方案一绝对是更合适的选择。
总结
别纠结targets了,直接在内部组件上引用#{cc.attrs.action}是最简洁且有效的方式,完全支持你这种动态ID的场景。
内容的提问来源于stack exchange,提问作者Dvir
相关产品推荐
相关产品推荐

