3

我正在尝试创建一个自定义组件来扩展 PrimeFaces。

我在 test 命名空间下有一个名为 textInput 的简单组件,它简单地调用 PrimeFaces textInput 组件并打印出传递给名为 fieldClass 的属性的值以及传递的任何属性的名称

如果我将 fieldClass 作为字符串传递:

<test:textInput id="foo" fieldClass="field-foo" />

这是结果

fieldClass = field-foo

[com.sun.faces.facelets.MARK_ID, fieldClass]

如果我将 fieldClass 作为表达式传递

<ui:param name="bar" value="field-foo"/>
<test:textInput id="foo" fieldClass="#{bar}" />

fieldClass 消失

fieldClass = NONE

[com.sun.faces.facelets.MARK_ID]

我如何真正掌握传递给组件的属性?

自定义组件使用的类如下:

test.components.ExtendInputTextRenderer

package test.components;

import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.FacesRenderer;
import org.primefaces.component.inputtext.*;

@FacesRenderer( 
     componentFamily=ExtendInputText.COMPONENT_FAMILY, 
     rendererType=ExtendInputTextRenderer.RENDERER_TYPE 
) 

public class ExtendInputTextRenderer extends InputTextRenderer {
     public static final String RENDERER_TYPE = "com.example.ExtendInputTextRenderer";

     @Override
     public void encodeEnd(FacesContext context, UIComponent component)
                throws java.io.IOException {
          ResponseWriter writer = context.getResponseWriter();
          Map attrs = component.getAttributes();
          String fieldClass = attrs.containsKey("fieldClass") ? (String) attrs.get("fieldClass").toString() : "NONE";
          writer.write("fieldClass = " + fieldClass + "<br/>");
          writer.write(attrs.keySet().toString() + "<br/>");
          super.encodeEnd(context, component);
     }
}

test.components.ExtendInputText

package test.components;

import javax.faces.component.FacesComponent;
import org.primefaces.component.inputtext.InputText;



@FacesComponent(ExtendInputText.COMPONENT_TYPE) 
public class ExtendInputText extends InputText { 
 
     public static final String COMPONENT_FAMILY = "com.example"; 
     public static final String COMPONENT_TYPE = "com.example.ExtendInputText"; 
 
     @Override 
     public String getFamily() { 
          return COMPONENT_FAMILY; 
     } 
 
     @Override 
     public String getRendererType() { 
          return ExtendInputTextRenderer.RENDERER_TYPE; 
     } 
}
4

1 回答 1

3
String fieldClass = attrs.containsKey("fieldClass") ? (String) attrs.get("fieldClass").toString() : "NONE";

您的错误是您containsKey()用于检查是否已指定属性。

UIComponent#getAttributes()这是javadoc的摘录:

获取属性

public abstract java.util.Map<java.lang.String,java.lang.Object> getAttributes()

返回一个可变Map的表示与 this 关联的属性(和属性,见下文)UIComponent,以属性名称(必须是 a String)为键。返回的实现必须支持所有标准和可选Map方法,并支持以下附加要求:

  • Map实现必须实现java.io.Serializable接口。
  • 任何添加键或值的尝试都null必须抛出NullPointerException.
  • 任何添加不是String必须的键的尝试都会抛出ClassCastException.
  • 如果指定为键的属性名称与 thisUIComponent的实现类的属性匹配,则以下方法将具有特殊行为:
    • containsKey()- 返回false
    • get()- 如果属性可读,则调用getter方法并返回返回值(将原始值包装在其对应的包装类中);否则抛出IllegalArgumentException
    • put()- 如果属性是可写的,则调用 setter 方法来设置相应的值(在其相应的包装类中展开原始值)。如果该属性不可写,或者尝试将原始类型的属性设置为null,则抛出IllegalArgumentException
    • remove()- 投掷IllegalArgumentException

请注意,它因此总是返回falseforcontainsKey组件的属性。这是因为动态属性不存储在属性映射中,而是存储在组件实例本身中。他们只在调用时解决get()

您需要按如下方式更改错误的行:

String fieldClass = (String) attrs.get("fieldClass");
if (fieldClass == null) fieldClass = "NONE";
于 2012-06-26T11:00:13.987 回答