因此,请选择像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大师可以向我解释这个方法尝试完成什么以及为什么somes属性调用这个方法而其他方法没有?非常感谢你
答案 0 :(得分:5)
它与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 }
canBeOptimized()
如果true
是标准JSF组件之一(实际上,如果组件的包名称以component
开头)并且如果没有,则返回javax.faces.component.
behaviors
数组中的多个行为。
renderPassThruAttributesOptimized()
只会呈现setAttributes
参数中指定的属性。
renderPassThruAttributesUnoptimized()
将遍历attributes
映射中的每个属性,如果关联的值不为null / empty,则检查每个属性,然后再渲染它。
至于为什么某些属性没有被handleAttribute()
设置,这是因为它们需要一些更具体的前/后处理,并且已经由特定于组件的渲染器显式呈现,因此它们不需要被渲染为“pass-thru”属性。
编写自定义组件时无需担心这一点。您始终可以引入与此类似的优化,但不建议依赖Mojarra特定的内部优化,因为例如,当您使用MyFaces时,它们可能根本不起作用。