本文介绍了组件族、组件类型和渲染器类型之间的关系是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I am learning custom component development in JSF, I got confused with the relationship between component family, component type and renderer type. For example, I registered a renderer and a custom component as shown below.

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 文件中注册了一个新标签,如下所示:

I also registered a new tag in my.taglib.xml file as below:

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

这个配置效果很好.但是,我不明白为什么渲染器注册需要 行.在 my.taglib.xml 中,组件和渲染器是连接的,恕我直言,为组件选择合适的渲染器就足够了.附加参数有什么用?

This configuration works very well. However, I didn't understand why the line <component-family>javax.faces.Panel</component-family> is required on renderer registration. In my.taglib.xml, the component and the renderer is connected and, IMHO, it should have been enough to select an appropriate renderer for the component. What is the use of the additional parameter <component-family>?

我做了谷歌研究,我得到的所有答案都说一个渲染器可以用来渲染多个组件.这些组件属于一个家族".但这些陈述并没有消除我的困惑.有人能解释一下组件类型、组件族和渲染器选择策略之间的关系吗?(希望有一个很好的例子.)

I did Google researches and all the answers I got say like "One renderer can be used to render multiple components. These components belong to one family". But these statements didn't clear my confusion up. Can someone explain the relationship between component type, component family and renderer selection strategy? (Hopefully with a good example.)

推荐答案

渲染器是由组件系列选择的,而不是您预期的组件类型.

The renderer is selected by the component family, not by the component type as you seem to expect.

让我们引用 JSF 2.0 规范:

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

每个标准用户界面组件类都有一个组件族的标准值,用于查找与该组件关联的渲染器.通用 UIComponent 类的子类通常会从其超类继承此属性,因此只需要超类的渲染器仍然能够处理专门的子类.

Each standard user interface component class has a standard value for the component family, which is used to look up renderers associated with this component. Subclasses of a generic UIComponent class will generally inherit this property from its superclass, so that renderers who only expect the superclass will still be able to process specialized subclasses.

基本上,为了通过Application#createComponent() 方法.

Basically, the component type is mandatory for JSF in order to create the component by Application#createComponent() method.

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

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

This has the advantage that the component study.faces.Div is not a compile time dependency and thus offers runtime polymorphism and pluggability possibilities (if you're familiar with JDBC's Class#forName() mechanism and its factories, then you'll understand that part better).

每个组件类型都属于一个系列,该系列可以由一个或多个组件组成.RenderKit#getRenderer()

Each component type belongs to a family which can consist of one or more components. The renderer is selected based on the component family and renderer type by RenderKit#getRenderer()

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

根据组件类型和渲染器类型选择渲染器.这允许为属于一个组件系列的多个组件类型重用渲染器.否则,即使组件可以共享相同的渲染器,您也需要为每个组件注册一个渲染器.

The renderer is not selected based on the component type and renderer type. This allows for the reuse of the renderer for multiple component types belonging to a component family. Otherwise you'd need to register a single renderer for every single component even though the components could share the same renderer.

下面的faces-config.xml条目

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

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

tells JSF that the Application should create an instance of the given component class whenever a component of the given component type is to be created. The component family is not specified in there, because that's already implicitly known by 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 应该返回给定渲染器类的实例.

tells JSF that the RenderKit should return an instance of the given renderer class whenever a renderer of the given component family and renderer type is been requested.

下面的.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 中定义),并且它的渲染器类型应设置为给定的渲染器类型.请注意,组件类型用于选择渲染器,而是用于在视图根中创建组件.另请注意,渲染器类型条目是可选的.否则将使用组件自己的预定义渲染器类型.这允许使用不同的渲染器类型重用现有的组件类型.

tells JSF (well, Facelets) that the given tag should create a component of the given component type in the view root (whose class is been definied in faces-config.xml) and that its renderer type should be set to the given renderer type. Note that the component type is not used to select the renderer, instead it is used to create a component in the view root. Also note that the renderer type entry is optional. Otherwise component's own predefinied renderer type will be used. This allows for reusing existing component types with a different renderer type.

这篇关于组件族、组件类型和渲染器类型之间的关系是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-03 17:32