我创建了一个组件,用于访问基于数字转换为其他类型的通用对象。我在请求映射中使用“var”属性,以允许组件中的子级访问该对象。当尝试访问子组件中由“var”命名的对象时,我得到以下异常: javax.el.PropertyNotFoundException:目标无法访问,标识符'objectName'已解析为null。
这是我的组件代码和标记:
@FacesComponent(value = "components.AgendaItemTextAccessor", createTag = true)
public class AgendaItemTextAccessor extends UIComponentBase{
public String getVar(){
return (String) getStateHelper().eval("var");
}
public void setVar(String var){
getStateHelper().put("var", var);
}
public AgendaItemText getValue(){
return (AgendaItemText) getStateHelper().eval("value");
}
public void setValue(AgendaItemObject text){
getStateHelper().put("value", text);
}
@Override
public boolean getRendersChildren() {
return true;
}
@Override
public void encodeChildren(FacesContext context) throws IOException{
if ((context == null)){
throw new NullPointerException();
}
AgendaItemText text = (AgendaItemText)getValue();
String varname = getVar();
Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
Object varStore = requestMap.get(varname); // in case this Object already exists in the requestMap,
// emulate "scoped behavior" by storing the value and
// restoring it after all rendering is done.
if(text != null){
requestMap.put(varname, text);
for(UIComponent child: getChildren()){
child.encodeAll(context);
}
// restore the original value
if(varStore != null){
requestMap.put(varname, varStore);
}else{
requestMap.remove(varname);
}
}
}
@Override
public String getFamily() {
return "components.AgendaItemTextAccessor";
}
标记
<xx:agendaItemTextAccessor value="#{itemValue}" var="itemVar">
<p:inputText value="#{itemVar.text}">
<p:ajax event="blur" listener="#{Controller.printMe(itemVar)}" />
</p:inputText>
</xx:agendaItemTextAccessor>
答案 0 :(得分:1)
我们被指示创建一个组件,该组件接受抽象对象并基于定义其类型的字段将其强制转换
你在实现功能要求方面走错了方向。 out
增加了不必要的复杂性。只需直接使用var
即可。在EL中,无论如何都是#{itemValue}
(反射,你知道),因此在将它放回EL之前绝对不需要向上,向下,向左或向右倾斜。
Object
关于具体问题,您遇到了这个问题,因为您只在<p:inputText value="#{itemValue.text}">
<p:ajax event="blur" listener="#{controller.printMe(itemValue)}" />
</p:inputText>
期间而不是在encodeChildren()
,processDecodes()
,processValidators()
和processUpdates()
期间设置了它。换句话说,它仅在呈现响应阶段期间可用,而不是在可能相关的所有其他阶段期间可用。遗憾的是,你没有在任何地方显示完整的堆栈跟踪,但它应该指出哪个阶段是有罪的(我的有根据的猜测说broadcast()
)。通常,processValidators()
仅在转发器或仅输出组件中实现。查看source code of var
如何正确操作(并查看source code的<o:tree>
如何以干的方式执行此操作。)