访问传递给扩展PrimeFaces组件的属性 [英] Accessing attributes passed to extended PrimeFaces component

查看:90
本文介绍了访问传递给扩展PrimeFaces组件的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to create a custom component to extend PrimeFaces.

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

I have a simple component called textInput under the test namespace that simply calls the PrimeFaces textInput component and prints out the value passed to an attribute named fieldClass and the names of any attributes passed

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

if I pass fieldClass as a string:

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

这是结果

fieldClass = field-foo

fieldClass = field-foo

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

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

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

If I pass fieldClass as an expression

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

fieldClass消失

fieldClass vanishes

fieldClass = NONE

fieldClass = NONE

[com.sun.faces.facelets.MARK_ID]

[com.sun.faces.facelets.MARK_ID]

我实际上如何掌握传递给组件的属性?

How do I actually get hold of the attributes passed to the component?

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

Classes used by the custom component follows:

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; 
     } 
}

推荐答案

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

您的错误是您正在使用containsKey()检查属性是否已指定.

Your mistake is that you're using containsKey() to check if the property has been specified.

以下是的摘录UIComponent#getAttributes() javadoc :

Here's an extract from UIComponent#getAttributes() javadoc:

getAttributes

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

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

Return a mutable Map representing the attributes (and properties, see below) associated wth this UIComponent, keyed by attribute name (which must be a String). The returned implementation must support all of the standard and optional Map methods, plus support the following additional requirements:

  • Map实现必须实现java.io.Serializable接口.
  • 任何尝试添加null键或值的操作都必须抛出NullPointerException.
  • 任何尝试添加不是String的键的操作都必须抛出ClassCastException.
  • 如果指定为键的属性名称与该UIComponent的实现类的属性匹配,则以下方法将具有特殊的行为:
    • containsKey()-返回false.
    • get()-如果该属性可读,则调用getter方法并返回返回的值(将原始值包装在其对应的包装器类中);否则,返回false.否则抛出IllegalArgumentException.
    • put()-如果该属性是可写的,则调用setter方法以设置相应的值(将原始值包装在其相应的包装器类中).如果该属性不可写,或者试图将原始类型的属性设置为null,则抛出IllegalArgumentException.
    • remove()-抛出IllegalArgumentException.
    • The Map implementation must implement the java.io.Serializable interface.
    • Any attempt to add a null key or value must throw a NullPointerException.
    • Any attempt to add a key that is not a String must throw a ClassCastException.
    • If the attribute name specified as a key matches a property of this UIComponent's implementation class, the following methods will have special behavior:
      • containsKey() - Return false.
      • get() - If the property is readable, call the getter method and return the returned value (wrapping primitive values in their corresponding wrapper classes); otherwise throw IllegalArgumentException.
      • put() - If the property is writeable, call the setter method to set the corresponding value (unwrapping primitive values in their corresponding wrapper classes). If the property is not writeable, or an attempt is made to set a property of primitive type to null, throw IllegalArgumentException.
      • remove() - Throw IllegalArgumentException.

      请注意,因此对于组件的属性,它总是为containsKey返回false.这是因为动态属性未存储在属性映射中,而是存储在组件实例本身中.仅在调用get()时才会解决.

      Note that it thus always returns false for containsKey for component's properties. That's because dynamic properties are not stored in the attribute map, but instead in the component instance itself. They're only resolved when calling get().

      您需要按以下步骤更改错误的行:

      You need to change the wrong line as follows:

      String fieldClass = (String) attrs.get("fieldClass");
      if (fieldClass == null) fieldClass = "NONE";
      

      这篇关于访问传递给扩展PrimeFaces组件的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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