当前位置: 首页 > 面试题库 >

组件族,组件类型和渲染器类型之间有什么关系?

夏侯航
2023-03-14
问题内容

当我学习JSF中的自定义组件开发时,我对组件族,组件类型和渲染器类型之间的关系感到困惑。例如,我注册了渲染器和自定义组件,如下所示。

faces-config.xml

<component>
    <component-type>study.faces.Div</component-type>
    <component-class>javax.faces.component.UIPanel</component-class>
</component>

<render-kit>
    <render-kit-id>HTML_BASIC</render-kit-id>
    <renderer>
        <component-family>javax.faces.Panel</component-family>
        <renderer-type>study.faces.DivRenderer</renderer-type>
        <renderer-class>com.study.ui.DivRenderer</renderer-class>
    </renderer>
</render-kit>

我还在my.taglib.xml文件中注册了一个新标签,如下所示:

<tag>
    <tag-name>div</tag-name>
    <component>
        <component-type>study.faces.Div</component-type>
        <renderer-type>study.faces.DivRenderer</renderer-type>
    </component>
</tag>

此配置效果很好。但是,我不明白为什么<component-family>javax.faces.Panel</component-family>渲染器注册需要该行。在中my.taglib.xml,已连接组件和渲染器,恕我直言,应该已经足够为该组件选择合适的渲染器。附加参数有<component-family>什么用?

我对Google进行了研究,得出的所有答案都是“一个渲染器可用于渲染多个组件。这些组件属于一个家族”。但是这些陈述并没有消除我的困惑。有人可以解释组件类型,组件系列和渲染器选择策略之间的关系吗?(希望有一个很好的例子。)


问题答案:

渲染器是通过组件系列选择的,而不是您期望的那样通过组件类型选择的。

让我们列举一下JSF2.0规范:

3.1.2组件类型

虽然不是UIComponent的属性,但是组件类型是与每个UIComponent子类相关的重要数据,它允许Application实例创建UIComponent具有该类型的子类的新实例。有关组件类型的更多信息,请参见第7.1.11节“对象工厂”。

3.1.3组件族

每个标准用户界面组件类都有一个针对组件系列的标准值,该标准值用于查找与此组件关联的渲染器。泛型UIComponent类的子类通常会从其超类继承此属性,以便仅期望超类的渲染器仍然能够处理专门的子类。

基本上,组件类型对于JSF是必需的,以便通过Application#createComponent()方法创建组件。

UIComponent component = context.getApplication().createComponent("study.faces.Div");

这样做的好处是该组件study.faces.Div不是编译时依赖项,因此提供了运行时多态性和可插入性的可能性(如果您熟悉JDBC的Class#forName()机制及其工厂,那么您会更好地理解该部分)。

每种组件类型都属于一个家族,该家族可以包含一个或多个组件。根据组件系列和渲染器类型选择渲染器,方法是RenderKit#getRenderer()

Renderer renderer = context.getRenderKit().getRenderer(component.getFamily(), component.getRendererType());

在渲染器
基于所述组件类型和渲染器类型选择。这允许渲染器重新用于属于一个组件族的多个组件类型。否则,即使组件可以共享相同的渲染器,也需要为每个组件注册一个渲染器。

以下faces-config.xml条目

<component>
    <component-type>study.faces.Div</component-type>
    <component-class>javax.faces.component.UIPanel</component-class>
</component>

告诉JSF,Application每当要创建给定组件类型的组件时,都应创建给定组件类的实例。没有在其中指定组件系列,因为已经隐式知道了component.getFamily()

和以下faces-config.xml条目

<render-kit>
    <renderer>
        <component-family>javax.faces.Panel</component-family>
        <renderer-type>study.faces.DivRenderer</renderer-type>
        <renderer-class>com.study.ui.DivRenderer</renderer-class>
    </renderer>
</render-kit>

告诉JSF,RenderKit每当请求给定组件族和渲染器类型的渲染器时,都应返回给定渲染器类的实例。

以下.taglib.xml条目

<tag>
    <tag-name>div</tag-name>
    <component>
        <component-type>study.faces.Div</component-type>
        <renderer-type>study.faces.DivRenderer</renderer-type>
    </component>
</tag>

告诉JSF(好吧,Facelets),给定的标签应该在视图根中创建给定组件类型的组件(其类在中定义faces- config.xml),并且其渲染器类型应该设置为给定的渲染器类型。请注意,组件类型 用于选择渲染器,而是用于在视图根目录中创建组件。另请注意,渲染器类型条目是可选的。否则,将使用组件自己的预定义渲染器类型。这允许使用其他渲染器类型重用现有组件类型。



 类似资料:
  • 非常简单的例子:我的App.js文件读取 我的Test.js文件上写着 在控制台中,渲染总是打印两次。为什么啊?

  • 问题内容: 它们有何不同?我有点困惑,因为它们似乎是相似的概念。 了解它们如何帮助优化编译时间? 问题答案: 从Swift自己的文档中: 类型安全 Swift是一种类型安全的语言。类型安全的语言鼓励您清楚代码可以使用的值的类型。 如果代码的一部分需要一个String,则不能错误地将其传递给Int。 类型推断 如果您 未 指定所需的值类型,则Swift会使用类型推断来得出适当的类型。通过类型推断,编

  • 问题内容: 您能否帮助您理解本机int类型与numpy.int32或numpy.int64类型之间的主要区别(如果有)? 问题答案: 观察差异的另一种方法是询问两种对象有什么方法。 在Ipython中,我可以使用tab complete来查看方法: 方法和属性: “经营者” 方法和属性(或属性)。一些相同,但更多的是,基本上所有的: 该方法看起来很像的。他们可以做同样的数学。 在很多方面与0d数组

  • 我真的不知道react router中render和component prop in Route之间的区别,在文档中它说render不创建新元素,但component创建新元素,我试图返回历史,但我发现在使用render in Route时调用componentWillMount,“如果为组件属性提供内联函数,则在每次渲染时都会创建一个新组件。这将导致现有组件卸载和新组件装载,而不仅仅是更新现有

  • 问题内容: 这是过去的考试问题,我想知道什么是原始类型和引用类型?对于数组,我知道引用类型是由对象或变量组成的数组,而原始类型是仅使用int或字符串创建数组的类型。(对?) 您认为您会如何回答测试中的问题并获得良好的信誉?如果没有真正直接引用原始的ARRAY类型,有没有办法做到这一点?还是您只用数组解释一下就可以了。 问题答案: 这些是Java中的原始类型: boolean byte short

  • 问题内容: 我已将JTable设置为在同一列中显示String和Boolean值。我有以下代码来设置两种对象类型的渲染器。 我面临的问题是,总是调用Object的渲染器,而不是布尔值或字符串。我尝试删除对象的渲染器,仍然没有运气。 问题答案: 我已将JTable设置为在同一列中显示String和Boolean值 然后,您不能只使用普通的渲染逻辑。 通常,根据方法返回的值选择渲染器。但是,这是基于列