JSF 2.2中自定义复合组件能否传递直通属性至包装组件?
JSF 2.2复合组件传递直通属性给包装组件的方法
当然可以!JSF 2.2专门引入了**直通属性(Pass-through Attributes)**特性,完美解决你想把复合组件上的额外属性直接传给内部原生组件的需求。下面我给你几种常用的实现方式,结合示例讲清楚:
1. 自动传递所有未声明的属性
这种方式最省心,不管你在复合组件上加了什么没在接口里定义的属性,都会自动传给内部的h:commandLink。
复合组件声明(my:commandLink)
<cc:interface xmlns:cc="http://xmlns.jcp.org/jsf/composite"> <!-- 只声明我们需要主动处理的属性 --> <cc:attribute name="text" type="java.lang.String" /> </cc:interface> <cc:implementation xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:commandLink value="#{cc.attrs.text}"> <!-- 关键:这个标签会把复合组件上所有未声明的属性传递给父组件(这里就是h:commandLink) --> <cc:passThroughAttributes /> </h:commandLink> </cc:implementation>
或者你也可以用直通属性的命名空间写法,效果完全一致:
<cc:implementation xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:a="http://xmlns.jcp.org/jsf/passthrough"> <h:commandLink value="#{cc.attrs.text}" a:passthrough="#{cc.passThroughAttributes}" /> </cc:implementation>
2. 显式指定要传递的属性
如果只想传递特定几个属性,不想什么都传,可以在接口里明确声明要传递的直通属性:
复合组件声明
<cc:interface xmlns:cc="http://xmlns.jcp.org/jsf/composite"> <cc:attribute name="text" type="java.lang.String" /> <!-- 明确列出要传递的属性 --> <cc:passThroughAttribute name="style" /> <cc:passThroughAttribute name="onclick" /> </cc:interface> <cc:implementation xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:commandLink value="#{cc.attrs.text}"> <cc:passThroughAttributes /> </h:commandLink> </cc:implementation>
3. 传递JSF标准组件属性(比如action、rendered)
上面的方法主要处理HTML原生属性,如果要传递action、rendered这类JSF标准组件属性,需要稍微调整:在接口里声明属性并指定目标组件ID:
复合组件声明
<cc:interface xmlns:cc="http://xmlns.jcp.org/jsf/composite"> <cc:attribute name="text" type="java.lang.String" /> <!-- 声明action属性,指定传给内部的internalLink组件 --> <cc:attribute name="action" targets="internalLink" /> <cc:attribute name="rendered" targets="internalLink" /> </cc:interface> <cc:implementation xmlns:h="http://xmlns.jcp.org/jsf/html"> <!-- 给内部组件加个ID,和上面的targets对应 --> <h:commandLink id="internalLink" value="#{cc.attrs.text}"> <cc:passThroughAttributes /> </h:commandLink> </cc:implementation>
使用示例
不管用哪种方式,你在页面里使用复合组件时,直接加属性就行:
<my:commandLink text="点击触发动作" style="color: #ff4444; cursor: pointer;" onclick="console.log('准备触发请求')" action="#{myBean.doSomething}" rendered="#{myBean.isLinkVisible}" />
这样所有指定的属性都会准确传递给内部的h:commandLink组件,完全符合你的需求~
内容的提问来源于stack exchange,提问作者Xavier Portebois




