未在 ValueExpression 上调用 JSF 自定义组件属性 setter
JSF Custom component attribute setter not called on ValueExpression
所以,我有一个非常烦人的问题。我创建了 JSF 自定义组件 class:
@FacesComponent(value = Column.COMPONENT_TYPE)
public class Column extends HtmlColumn {
...
protected enum attr {
sort, search ...
我有所有 attr
的 setter 和 getter,它们看起来像这样:
public void setSort(java.lang.Object sort) {
getStateHelper().put(attr.sort, sort);
}
public java.lang.Object getSort() {
return getStateHelper().eval(attr.sort, null);
}
public void setSearch(java.lang.Object search) {
getStateHelper().put(attr.search, search);
}
public java.lang.Object getSearch() {
return getStateHelper().eval(attr.search, null);
}
因为我使用 StateHelper 接口来设置组件的属性值,所以我期望这些设置器应该与 ValueExpression
一起工作,但它们不是。
这是我尝试设置排序和搜索属性的 .xhtml 片段:
<e:dataTable id="datatable" var="entity" value="#{output.entities}"
entryId="#{entity.id}">
<e:column columnHeader="ID" sort="#{entity.id}" search="#{entity.id}">
<h:outputText value="#{entity.id}"/>
</e:column>
当我使用非值表达式值时它有效,但在这种情况下不是一个选项。
如果对您有帮助,这里是 taglib 的一部分:
<tag>
<tag-name>column</tag-name>
<component>
<component-type>component.Column</component-type>
</component>
<attribute>
<name>rendered</name>
<required>false</required>
<type>java.lang.Boolean</type>
</attribute>
<attribute>
<name>visible</name>
<required>false</required>
<type>java.lang.Boolean</type>
</attribute>
<attribute>
<name>sort</name>
<required>false</required>
</attribute>
<attribute>
<name>search</name>
<required>false</required>
</attribute>
<attribute>
<name>columnHeader</name>
<required>false</required>
<type>java.lang.String</type>
</attribute>
...
</tag>
注意:我们不对数据表和列使用 primefaces 或任何其他 *faces 库,因为它根本无法满足我们的需求。
有没有想过为什么我的二传手不工作以及如何让它工作?谢谢。
由于 BalusC 指出此行为是预期的,因此我调试了 setValueExpression()
方法。因此,如果您像我在问题中所做的那样向属性提供 ValueExpression
,则不应调用 setter(我认为应该调用)。值表达式由 setValueExpression
方法处理。
问题是当我调用 getSort()
或 getSearch()
方法时,我得到的是空值(默认评估值)。所以我将我的 getters 编辑成这样:
public java.lang.Object getSort() {
Object sort = getStateHelper().eval(attr.sort, null);
if (sort == null) {
ValueExpression ve = getValueExpression("sort");
if (ve != null) {
ELContext context = FacesContext.getCurrentInstance().getELContext();
sort = ve.getValue(context);
}
}
return sort;
}
现在一切正常。但我必须指出,这种行为(setter 不调用提供的值表达式)不是很直观,可能会造成混淆。
所以,我有一个非常烦人的问题。我创建了 JSF 自定义组件 class:
@FacesComponent(value = Column.COMPONENT_TYPE)
public class Column extends HtmlColumn {
...
protected enum attr {
sort, search ...
我有所有 attr
的 setter 和 getter,它们看起来像这样:
public void setSort(java.lang.Object sort) {
getStateHelper().put(attr.sort, sort);
}
public java.lang.Object getSort() {
return getStateHelper().eval(attr.sort, null);
}
public void setSearch(java.lang.Object search) {
getStateHelper().put(attr.search, search);
}
public java.lang.Object getSearch() {
return getStateHelper().eval(attr.search, null);
}
因为我使用 StateHelper 接口来设置组件的属性值,所以我期望这些设置器应该与 ValueExpression
一起工作,但它们不是。
这是我尝试设置排序和搜索属性的 .xhtml 片段:
<e:dataTable id="datatable" var="entity" value="#{output.entities}"
entryId="#{entity.id}">
<e:column columnHeader="ID" sort="#{entity.id}" search="#{entity.id}">
<h:outputText value="#{entity.id}"/>
</e:column>
当我使用非值表达式值时它有效,但在这种情况下不是一个选项。
如果对您有帮助,这里是 taglib 的一部分:
<tag>
<tag-name>column</tag-name>
<component>
<component-type>component.Column</component-type>
</component>
<attribute>
<name>rendered</name>
<required>false</required>
<type>java.lang.Boolean</type>
</attribute>
<attribute>
<name>visible</name>
<required>false</required>
<type>java.lang.Boolean</type>
</attribute>
<attribute>
<name>sort</name>
<required>false</required>
</attribute>
<attribute>
<name>search</name>
<required>false</required>
</attribute>
<attribute>
<name>columnHeader</name>
<required>false</required>
<type>java.lang.String</type>
</attribute>
...
</tag>
注意:我们不对数据表和列使用 primefaces 或任何其他 *faces 库,因为它根本无法满足我们的需求。
有没有想过为什么我的二传手不工作以及如何让它工作?谢谢。
由于 BalusC 指出此行为是预期的,因此我调试了 setValueExpression()
方法。因此,如果您像我在问题中所做的那样向属性提供 ValueExpression
,则不应调用 setter(我认为应该调用)。值表达式由 setValueExpression
方法处理。
问题是当我调用 getSort()
或 getSearch()
方法时,我得到的是空值(默认评估值)。所以我将我的 getters 编辑成这样:
public java.lang.Object getSort() {
Object sort = getStateHelper().eval(attr.sort, null);
if (sort == null) {
ValueExpression ve = getValueExpression("sort");
if (ve != null) {
ELContext context = FacesContext.getCurrentInstance().getELContext();
sort = ve.getValue(context);
}
}
return sort;
}
现在一切正常。但我必须指出,这种行为(setter 不调用提供的值表达式)不是很直观,可能会造成混淆。