6

我根据许多教程之一创建了我的自定义JSF组件(我正在使用PrimeFaces),我添加了一个已成功传递给组件的参数。

<c:custom command="command"/>
public void setCommand(String command) {
    log.debug("setCommand {}", command);
    this.command = command;
}

但是我需要自定义类型的参数,这是我在教程中找不到的东西,教程只处理最琐碎的情况。

<c:custom image="#{currentImageBean.image}"/>
public void setImage(Object image) {
    log.debug("setImage {}", image);
    this.image = (Image) image;
}

bean 正在返回Image类型的对象,但未调用 setter。我预计这会起作用,因为否则一个好的教程应该提到这种情况,但现在我被更糟糕的错误所困扰:没有任何反应,日志中没有任何内容表明原因......所以,出了什么问题,我需要改变什么,在哪里寻找潜在的错误?

4

1 回答 1

6

这与自定义类型无关。这与使用文字(静态)值与 EL 相比,如attributename="attributevalue"attributename="#{attribute.value}".

这种行为是预期的并且是规范的。ValueExpressionEL 表达式 ( s) 的属性值由 设置UIComponent#setValueExpression()。它们应该只在真正被请求时才被评估,通常是在视图渲染期间。在烘焙实例期间不应直接UIComponent评估它们,因为这会破坏动态值表达式的性质(考虑取决于数据表的当前迭代轮次)。

更好的是将可以保存 EL 值表达式的属性的 getter/setter 委托UIComponent#getStateHelper()给本地属性,而不是本地属性。setValueExpression()遗嘱最终也归结于StateHelperUIComponent#getAttributes()还解析来自 的值StateHelper

public Image getImage() {
   return (Image) getStateHelper().eval("image");
}

public void setImage(Image image) {
    getStateHelper().put("image", image);
}

请注意,没有本地属性。因此,当您需要属性的(评估)值时,只需调用 getter。

为了实现您的初始功能要求,即设置属性的日志记录,您可能希望将日志记录语句添加到setValueExpression()委托给super.

@Override
public void setValueExpression(String name, ValueExpression binding) {
    log.debug(....);
    super.setValueExpression(name, binding);
}
于 2012-11-21T12:09:20.460 回答