【发布时间】:2013-01-04 16:50:51
【问题描述】:
动态实例化 PF 3.4.2 AutoComplete 组件时遇到问题。 组件最初渲染正常,其值在部分处理时刷新 但永远不会显示建议。
我正在通过以下方式实例化此控件:
AutoComplete ac = (AutoComplete) context.getApplication().createComponent(AutoComplete.COMPONENT_TYPE);
final String varName = "p";
ValueExpression ve = JSFUtils.createValueExpression("#{minContext.selected.sen}"), Sen.Type);
ac.setValueExpression("value", ve);
ac.setForceSelection(true);
ac.setVar(varName);
ValueExpression itemLabel = JSFUtils.createValueExpression("#{sc:senLibelle(p)}"), String.class);
ac.setValueExpression("itemLabel", itemLabel);
ValueExpression itemValue = JSFUtils.createValueExpression("#{" + varName + "}");
ac.setValueExpression("itemValue", itemValue);
MethodExpression completeMethod = JSFUtils.createMethodExpression("#{senUtils.completeAllSens}", List.class,new Class[]{String.class});
ac.setCompleteMethod(completeMethod);
然后使用将其添加到父控件
getChildrens().add(ac);
父组件是PF PanelGrid的派生。我成功地使用这种方法来生成各种版本面板,它就像一个魅力。但我不明白为什么它没有自动完成。
父控件看起来像:
@FacesComponent(SenatDataTableEntryDetail.SENAT_COMPONENT_TYPE)
public class SenatDataTableEntryDetail extends PanelGrid {
/** Leaving renderer unchanged, so that PF renderer for PanelGrid is used.
*/
public static final String SENAT_COMPONENT_FAMILY = "fr.senat.faces.components";
public static final String SENAT_COMPONENT_TYPE = SENAT_COMPONENT_FAMILY + ".SenatDataTableEntryDetail";
private enum PropertyKeys { mapper, bean; }
@Override
public void encodeBegin(FacesContext context) throws IOException {
super.encodeBegin(context);
addDynamicChildren(context);
}
@Override
public boolean getRendersChildren()
{
return true;
}
...
private Boolean isInitialized() {
return (Boolean)getStateHelper().eval(SENAT_INITIALIZED,false);
}
private void setInitialized(Boolean param) {
getStateHelper().put(SENAT_INITIALIZED, param);
}
private void addDynamicChildren(FacesContext context) throws IOException {
if(isInitialized()) {
return;
}
setInitialized(true);
/* components are instiated and added as children only once */
}
}
它只是将子元素添加到面板网格中。
自定义组件声明的其他方面(在taglib等)都可以。
问题似乎不在于 EL 表达式、completeMethod 定义等。如果我在我的测试 xhtml 页面中包含具有相同参数的 p:autoComplete 实例,它会按预期工作:
<p:autoComplete value="#{minContext.selected.sen}" forceSelection="true"
var="p" itemLabel="#{sc:senLibelle(p)}" itemValue="#{p}"
completeMethod="#{senUtils.completeAllSens}"/>
我注意到 PF AutoComplete 组件有点特别,因为它的渲染方式不同 当检测到查询时。请参阅http://primefaces.googlecode.com/files/primefaces-3.4.2.zip 中的 AutoCompleteRenderer 源代码。
在“动态实例化”的情况下,不会调用该组件的decode方法。我没能找到最后几天的原因,但没有成功。
我期待您就如何检查以纠正这个烦人的“错误”提出建议。
【问题讨论】:
-
我想我缩小了问题的根源。生成的客户 ID 类似于 j_id_xx 而不是 xxxx:yyyy:zzzz:j_id_xx。因此,该组件未正确添加到具有 id xxxxx 的组件的已修改子项集合中,并且未正确执行部分处理。
-
就是这样。由于我在实例化后没有设置组件父级,因此在生成客户端ID时找不到命名容器。所以,我只是这样做:
ac.setParent(this); ac.setId(...some application specific unique id generation...);并且它有效。
标签: jsf primefaces custom-component