Web*_*ter 2 jsf default composite-component jsf-2
我有一个JSF复合组件util_primefaces:inplace_name,它需要一个"管理器"支持bean,当编辑实体的'name'字段时(使用p:inplace)执行持久性更新:
<cc:interface>
<cc:attribute name="manager" type="com.example.web.AbstractManager" required="false" default="#{blockManager}"/>
<cc:attribute name="element" type="com.example.entity.Element" required="true"/>
<cc:attribute name="elid" required="true"/>
<cc:attribute name="update" required="false" default="@parent"/>
..
</cc:interface>
<cc:implementation>
..
<p:inplace id="#{cc.attrs.elid}" editor="true" emptyLabel="UNDEF" >
<p:ajax
event="save"
listener="#{cc.attrs.manager.onInplaceNameSaveEvent}"
process="@this #{cc.attrs.elid}-name"
update="#{cc.attrs.update}"
/>
<h:inputText id="#{cc.attrs.elid}-name" value="#{cc.attrs.element.name}"/>
..
Run Code Online (Sandbox Code Playgroud)
例如@ViewScoped @ManagedBean BlockManager最终扩展了一个AbstractManager,它有一个监听器方法:
public void onInplaceNameSaveEvent(AjaxBehaviorEvent ae).
Run Code Online (Sandbox Code Playgroud)
[ASIDE:这里描述了不寻常的"elid"属性的原因,它在这个问题中没有进一步的作用:Primefaces p:inplace:如何更优雅地传播实体合并的EL表达式 ]
当我调用复合组件传入一个显式的#{blockManager}(或AbstractManager的其他子类)时,它工作正常:
<util_primefaces:inplace_name
element="#{tenancy}"
elid="tenancy"
manager="#{blockManager}"
/>
Run Code Online (Sandbox Code Playgroud)
但是如果我没有传入#{blockManager},那么在执行inplace edit并保存时,我得到一个错误,即onInplaceNameSaveEvent(AjaxBehaviorEvent)方法未知:
<util_primefaces:inplace_name
element="#{tenancy}"
elid="tenancy"
/>
Run Code Online (Sandbox Code Playgroud)
错误是:
WARNING: Method not found: com.example.web.BlockManager@71396a88.onInplaceNameSaveEvent(javax.faces.event.AjaxBehaviorEvent)
javax.el.MethodNotFoundException: Method not found: com.example.web.BlockManager@71396a88.onInplaceNameSaveEvent(javax.faces.event.AjaxBehaviorEvent)
at com.sun.el.util.ReflectionUtil.getMethod(ReflectionUtil.java:155)
Run Code Online (Sandbox Code Playgroud)
问:为什么在复合组件属性中使用default ="#{blockManager}"未正确使用辅助bean?
根据标签的文档,cc:attributedefault必须将值评估为a java.lang.String.
这就是为什么#{blockManager}表达式不能正常工作,你只能设置String属性的默认值.
要查看会发生什么,您可以测试在taglib中注册以下函数(如此处所示):
public static String typeOf(Object o) {
return o == null ? null : o.getClass().toString();
}
Run Code Online (Sandbox Code Playgroud)
并在像这样的复合组件中使用它:
<ui:composition>
<cc:interface>
<cc:attribute name="param" type="java.lang.Integer" required="true"
default="1" />
</cc:interface>
<cc:implementation>
<h:outputText value="#{fnc:typeOf(cc.attrs.param)}" />
</cc:implementation>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)
现在,如果您使用组件而未指定param,如下所示:
<my:comp />
Run Code Online (Sandbox Code Playgroud)
...它将输出class java.lang.String,因为它使用ValueExpression的结果作为默认属性,即String "1".
当你指定param时:
<my:comp param="1" />
Run Code Online (Sandbox Code Playgroud)
...它输出class java.lang.Integer,因为它现在是由于强制转换为指定的类型而产生的值cc:attribute.
| 归档时间: |
|
| 查看次数: |
3249 次 |
| 最近记录: |