EL中的#{component}到底是什么?

What exactly is #{component} in EL?

根据https://code.google.com/p/primefaces/issues/detail?id=4720ComponentUtils.resolveWidgetVar(String expression, UIComponent component)函数自2013年起在Primefaces中可用。它可以通过"#{p:widgetVarFromContext(searchExpression, component)}"函数在EL中使用。

这在多个组件在不同 NamingContainer 中具有相同 ID 但仍存在于同一视图中的情况下非常有用。在这种情况下, #{p:widgetVar(searchExpression)} 函数仅 returns 找到最后一个。

但是我不明白如何引用必须作为 EL 的第二个参数传递的 UIComponent。上面提到的错误报告建议我们可以使用 #{component} 来引用它。谁能给我举个例子吗?

#{component} 是引用 current UIComponent in EL scope (see also implicit EL objects) 的隐式 EL 变量。您通常只能在组件的 HTML 属性或模板文本子项中引用它。

例如在 <h:inputText> 的情况下,它将引用 UIInput class 的实例,其中有一个 isValid() 方法。

<h:inputText id="foo" required="true"
    style="background: #{component.valid ? '' : 'pink'}"
    onclick="alert('Client ID of this component is #{component.clientId}');" />

您还可以使用 binding 属性让 JSF 在视图构建期间将对组件实例的引用放在 Facelet 范围内。这样,组件引用将在视图渲染期间在 Facelet 中的任何位置可用。

<script>alert('Client ID of foo component is #{foo.clientId}');</script>
<h:inputText binding="#{foo}" />

另请参阅:

  • Difference between client id generated by component.clientId and p:component()
  • JSF component binding without bean property
  • How does the 'binding' attribute work in JSF? When and how should it be used?

p:widgetVarFromContext 在引用复合组件内的 PrimeFaces 小部件时很有用。同一页面上可能有多个组件实例。所以写 widgetVar="expression"PF('expression') 是不可能的。会有多个具有相同名称的小部件。然后最好省略 widgetVar 属性并使用生成的唯一属性,因为它基于 clientId.

您不能在 <cc:implementation> 中使用 #{p:widgetVar('expression')},因为它会导致 Cannot find component for expression "expression" referenced from "j_id1" 错误,而不是预期的 PF('widget_expression').

但是您可以使用 #{p:widgetVarFromContext('expression', cc)},它将 return 类似于 PF('widget_wrapperform_compositecomponent1_expression')cc 指的是复合组件实例的根。