微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在我的应用程序的每个 p:selectOneMenu 中对 f:selectItems 进行排序?

如何解决如何在我的应用程序的每个 p:selectOneMenu 中对 f:selectItems 进行排序?

例如:

<p:selectOneMenu value="#{UserBean.country}" id="countryId">
    <f:selectItem itemLabel="Japan" itemValue="Japan"/>
    <f:selectItem itemLabel="Russia" itemValue="Russia"/>
    <f:selectItem itemLabel="India" itemValue="India"/>
    <p:ajax listener="#{UserBean.onChangeCountry}" process="@this"/>
</p:selectOneMenu>

像上面一样,我在其他 jsf 页面中有许多其他的 selectOneMenu 不是排序形式,我想要一个解决方案,其中使用自定义标记围绕 selectOneMenu 标记将按排序顺序显示内容(或者也可以建议任何其他方式我们可以做到这一点)

解决方法

您不需要自定义标签。

p:selectOneMenu 的情况下,您可以只使用 f:selectItems(复数)并返回一个排序的集合(替换您的个人 f:selectItem 标签)。在这种情况下,这将类似于;

<f:selectItems value="#{view.countries}"/>

其中 countries 是一个 getter,getCountries(),返回根据您的选择排序的 Map<String,String> 列表。

想象一下,虽然没有 f:selectItems,但我们唯一可用的选项是 f:selectItem(单数)——就像你的例子一样。那么解决方案是使用 JSF 预渲染钩子并在渲染该部分之前对 JSF 组件进行排序。你可以在这里阅读它是如何工作的; Variable order of components (panels) in JSF page。在该示例中,p:panel 组件列表在 h:panelGroup 中随机排列。不过,它可以很容易地应用于这种情况。

为了使它更透明并将f:event标签隐藏到页面上的预渲染挂钩,您可以更进一步定义一个复合组件;

https://stackoverflow.com/tags/composite-component/info

这个复合组件可以只使用一个 selectOneMenu 并引入一个 sort 属性,该属性允许您调用上述的排序预渲染钩子,具体取决于 {{1} } 属性为真或假。

,

您可以为 p:selectOneMenu 组件创建自定义渲染器。创建一个新类,例如 my.custom.MySelectOneMenuRenderer,并扩展 SelectOneMenuRenderer。在此,您希望将 @Override 方法encodeInput 改为:

public class MySelectOneMenuRenderer extends SelectOneMenuRenderer {

  @Override
  protected void encodeInput(FacesContext context,SelectOneMenu menu,String clientId,List<SelectItem> selectItems,Object values,Object submittedValues,Converter converter) throws IOException {
    // Sort the items
    Collections.sort(selectItems,Comparator.comparing(SelectItem::getLabel));
    // Delegate to super to continue rendering
    super.encodeInput(context,menu,clientId,selectItems,values,submittedValues,converter);
  }

}

我已经使用 PrimeFaces 10 进行了检查。如果您需要不同 PrimeFaces 版本的源代码,请选中 SelectOneMenuRenderer source code 并选择相应的版本标签。请注意,您需要覆盖的方法在其他版本中可能会有所不同(不太可能,但可能)。

将您的自定义渲染器添加到您的 render-kit 中的 faces-config.xml 部分,例如:

<render-kit>
  <renderer>
    <component-family>org.primefaces.component</component-family>
    <renderer-type>org.primefaces.component.SelectOneMenuRenderer</renderer-type>
    <renderer-class>my.custom.MySelectOneMenuRenderer</renderer-class>
  </renderer>
</render-kit>

请注意,对于任何 p:selectOneMenu 渲染,每次都会对选项进行排序,这会带来性能损失。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。