我正在尝试创建一个自定义UIData组件,我遇到了Ajax的麻烦。第一个调用工作正常,但后续调用无法解析我的UIData'var'属性。在尝试调试时,我可以看到第一个ajax调用恢复了我的自定义UIData并将'var'放入RequestMap。后续调用不再调用restoreState,导致空的'var'变量。
PS。对这篇文章的道歉并不是非常SSCCE,但它会非常大。
答案 0 :(得分:1)
问题在于我没有使用
UIComponentBase.restoreAttachedState(context, values[1]);
UIComponentBase.saveAttachedState(context, getValue());
保存并恢复状态
public Object saveState(FacesContext context)
public void restoreState(FacesContext context, Object state)
另一个问题是我没有重置UIData的rowIndex
setRowIndex(-1);
中的
public boolean visitTree(VisitContext context, VisitCallback callback)
这会导致使用索引调整保存状态的id,从而导致下一个恢复阶段的密钥丢失。
答案 1 :(得分:1)
虽然我的答案对某些人来说可能很有意思,但它没有回答如何解决UIData'var'。答案是在UIData处理的每个迭代/阶段中调用setRowIndex(int)方法,该方法使用请求映射中的dataModel的数据设置'var'属性(参见下面的摘录)。这是由UIData方法invokeOnComponent或UIData.visitTree()调用的,它由JSF 1.2中的FaceletViewHandlingStrategy.locateComponentByClientId()调用,或者由JSF2中的各个位置调用,包括状态管理策略,ViewContextImpl和许多其他:
请参阅-Tree访问下此链接中的更改 http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/
这是UIData的摘录:
String var = (String) getStateHelper().get(PropertyKeys.var);
if (var != null) {
Map<String, Object> requestMap =
getFacesContext().getExternalContext().getRequestMap();
if (rowIndex == -1) {
oldVar = requestMap.remove(var);
} else if (isRowAvailable()) {
requestMap.put(var, getRowData());
} else {
requestMap.remove(var);
if (null != oldVar) {
requestMap.put(var, oldVar);
oldVar = null;
}
}