【问题标题】:What does method handleAttribute(String name, Object value) inside UIComponent Mojarra is doing?UIComponent Mojarra 中的方法 handleAttribute(String name, Object value) 是做什么的?
【发布时间】:2012-08-04 23:55:25
【问题描述】:

所以让我们选择像HtmlSelectOneRadio这样的UIComponent(请在此处查看源代码:http://grepcode.com/file/repo1.maven.org/maven2/com.sun.faces/jsf-api/2.1.7/javax/faces/component/html/HtmlSelectOneRadio.java#HtmlSelectOneRadio

所以有些setter会调用方法handleAttribute(...),而有些则不会,例如

public void setDir(java.lang.String dir) {
    getStateHelper().put(PropertyKeys.dir, dir);
    handleAttribute("dir", dir);
}

public void setDisabled(boolean disabled) {
    getStateHelper().put(PropertyKeys.disabled, disabled);
}

我很不清楚handleAttribute 正在做什么,JSF 大师能否向我解释一下这种方法尝试完成什么以及为什么某些属性调用此方法而其他属性没有?非常感谢

【问题讨论】:

    标签: jsf jsf-2 mojarra


    【解决方案1】:

    它与 Mojarra 内部渲染优化有关,其中 由内部 handleAttribute() 方法设置的属性被渲染为所谓的“pass-thru”属性而不是那个组件的每个属性都会检查是否已设置,如果属性相对较多,最终可能会更昂贵。 “pass-thru”属性是一个组件属性,无需任何特定的预处理/后处理即可直接渲染。

    查看 Mojarra 的 RenderKitUtils 类,从 renderPassThruAttributes() 方法开始:

    316         if (canBeOptimized(component, behaviors)) {
    317             //noinspection unchecked
    318             List<String> setAttributes = (List<String>)
    319               component.getAttributes().get(ATTRIBUTES_THAT_ARE_SET_KEY);
    320             if (setAttributes != null) {
    321                 renderPassThruAttributesOptimized(context,
    322                                                   writer,
    323                                                   component,
    324                                                   attributes,
    325                                                   setAttributes,
    326                                                   behaviors);
    327             }
    328         } else {
    329 
    330             // this block should only be hit by custom components leveraging
    331             // the RI's rendering code, or in cases where we have behaviors
    332             // attached to multiple events.  We make no assumptions and loop
    333             // through
    334             renderPassThruAttributesUnoptimized(context,
    335                                                 writer,
    336                                                 component,
    337                                                 attributes,
    338                                                 behaviors);
    339         }
    

    如果component 是标准JSF 组件之一(实际上,如果组件的包名称以javax.faces.component. 开头)并且@987654331 中的行为不超过1 个,则canBeOptimized() 返回true @数组。

    renderPassThruAttributesOptimized() 只会渲染setAttributes 参数中指定的属性。

    renderPassThruAttributesUnoptimized() 将遍历 attributes 映射中的每个属性,并检查每个属性是否关联的值不为空/空,然后渲染它。


    至于为什么handleAttribute()没有设置某些属性,那是因为它们需要一些更具体的预处理/后处理,并且已经由特定于组件的渲染器显式渲染,因此不需要渲染作为“直通”属性。


    编写自定义组件时无需担心这一点。您始终可以引入与此类似的自己的优化,但不建议依赖 Mojarra 特定的内部优化,因为例如,当您使用 MyFaces 时,它们可能根本不起作用。

    【讨论】:

    • 假设我有一个logicalId 属性,如果设置了这个logicalId,我会将它作为id,而不是为它创建一个通用ID,所以根据你的说,这个属性不需要调用handleAttribute,因为它正在由我的渲染器处理。而 value 应该呈现为 pass-thru 属性。我理解对了吗,BalusC?
    • 仅当您为现有的标准 JSF 组件提供自定义渲染器,或者如果您在 javax.faces.component 包中包含自定义组件并且正在使用 Mojarra-自定义渲染器中的特定助手类/方法。
    • 顺便说一下,HtmlSelectOneRadio(实际上是UIInput)的value属性不是由handleAttribute()设置的。也许这只是一个坏例子?
    • 抱歉,我无法尽快回复您。因此,我需要在自定义渲染器中对其执行某些操作的自定义组件的任何属性都不应该是传递属性,对吗,BalusC?我问这些问题是因为我看到 PrimeFaces 在他们的 SelectOneRadio 组件上使用了这种方法。他们有OPTIMIZED_PACKAGE = "org.primefaces.component." 并在widgetVar 上调用handleAttribute,在他们的编码脚本中,他们执行writer.write("PrimeFaces.cw('SelectManyCheckbox','" + checkbox.resolveWidgetVar() + "',{"); 知道为什么需要widgetVar 传递属性BalusC
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-07-17
    相关资源
    最近更新 更多