我正在尝试创建一个自定义 UIData 组件,但我遇到了 Ajax 问题。第一次调用工作正常,但后续调用无法解析我的 UIData 'var' 属性。尝试调试时,我可以看到第一个 ajax 调用恢复了我的自定义 UIData 并将“var”放入 RequestMap。随后的调用虽然不会再次调用 restoreState ,但会导致一个空的“var”变量。
PS。很抱歉这篇文章不是非常 SSCCE,但它会非常大。
问题是我没有使用
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 与索引一起调整,从而在下一个恢复阶段导致键丢失。
虽然我的回答对某些人来说可能很有趣,但它没有回答 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;
}
}