具有属性值前pression语言JSF 2定制组件不触发属性二传手 [英] JSF 2 Custom components having Expression Language for attribute value don't trigger the attribute setter

查看:193
本文介绍了具有属性值前pression语言JSF 2定制组件不触发属性二传手的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JSF 2.0建立一个自定义组件

I have build a custom component in JSF 2.0

标签如下:

<x:myTag id="1" name="AAA" />

相应的Java类:

The corresponding java class:

@FacesComponent("a.b.c.MyTag")
public class UIMyTag extends UIInput {

   private String name;
   private String id;

   public String getId() {
      return id;
   }

   public void setId(String id) {
       this.id = id;
   }


   public String getId() {
      return id;
   }

   public void setId(String id) {
       this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   @Override
   public void encodeBegin(FacesContext context) throws IOException {
       ResponseWriter writer = context.getResponseWriter();
       logger.debug(getName()); //prints null for name="#{dummyBean.name}" 
                                //   and AAA for name="AAA"
       logger.debug(getAttributes().get("name")); // always correct value
   ...
}
   ....

}

如果我用

<x:myTag id="1" name="AAA" />

一切正常,但是当我使用EL为MyTag的属性的setName()方法不会被调用。因此,对于

everything works as expected, but when I use EL for myTag attributes the setName() method never gets called. So for,

<x:myTag id="#{dummyBean.id}" name="#{dummyBean.name}" />

我总是的内部名称属性我的连接codeBEGIN 方法。调试后,我已经注意到,的setName 方法不会被调用。我想,也许对于EL的东西弄乱的东西了(我仍然认为,其原因是与该),但什么是真正奇怪的是, ID 属性一起好:二传手被调用,并且该值是econding开始时预期。

I always get null for the name property inside my encodeBegin method. After debugging I've noticed that the setName method never gets called. I thought that maybe something regarding EL messes things up (and I still believe that the reason is related to that), but what's really weird is that the id property works good: the setter gets called, and the value is as expected when the econding begins.

我不得不提,如果我称之为的getAttributes()获取(名称)连接codeBEGIN 方法我得到正确的名称值,但我很好奇,为什么它不与getter和setter工作。

I have to mention that if I call getAttributes().get("name") from the encodeBegin method I get the correct name value, but I'm intrigued why it doesn't work with getter and setter.

任何想法缺少我的分量?

Any ideas what's missing to my component?

推荐答案

这是正常现象,并通过规范。属性这是价值前pressions由<一组值href=\"http://docs.oracle.com/javaee/6/api/javax/faces/component/UIComponent.html#setValueEx$p$pssion%28java.lang.String,%20javax.el.ValueEx$p$pssion%29\"><$c$c>UIComponent#setValueEx$p$pssion().他们即应该进行评估​​,只有当他们的真正的被使用,通常在视图渲染时间。

This behavior is expected and by specification. Attribute values which are value expressions are set by UIComponent#setValueExpression(). They are namely supposed to be evaluated only when they are really been used, usually during view render time.

ID (和结合)属性具有特殊的待遇:它在视图生成时评估的的它已经设置的,所以常规二传手会被调用,而不是 setValueEx pression()(因为视图渲染,否则会崩溃时,在 ID (或结合)属性动态地计算为一个不同的值,它是在视图生成时由于某些原因)。

The id (and binding) attribute has special treatment: it's evaluated during view build time before it's been set, so the "regular" setter would be called instead of the setValueExpression() (because rendering of the view would otherwise crash when the id (or binding) attribute dynamically evaluates to a different value than it was during the view build time for some reason).

更好的是委派getter / setter方法​​来<一href=\"http://docs.oracle.com/javaee/6/api/javax/faces/component/UIComponent.html#getStateHelper%28%29\"><$c$c>UIComponent#getStateHelper()代替本地特性。在 setValueEx pression()最终在 StateHelper (注意也结束了,这不叫二传手在所有;只是调用吸气,如果你需要的数据)和的getAttributes()也由 StateHelper

Better is to delegate the getters/setters to UIComponent#getStateHelper() instead of to local properties. The setValueExpression() ultimately also end up in the StateHelper (note that it doesn't call the setter at all; just call the getter if you need the data) and the getAttributes() also resolves the values from the StateHelper.

public String getName() {
   return (String) getStateHelper().eval("name");
}

public void setName(String name) {
    getStateHelper().put("name", name);
}

请注意,您可以放心的删除的的的getId() SETID()方法,因为他们已经definied在你从延长 UIComponentBase 超类。

Note that you can safely remove the getId() and setId() methods, because they're already definied in the UIComponentBase superclass which you're extending from.

这篇关于具有属性值前pression语言JSF 2定制组件不触发属性二传手的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆