java - JSF 页面中组件(面板)的可变顺序
问题描述
我想知道在 JSF(或其任何框架,例如 Primefaces)中是否有可能具有将在页面中显示的组件或更准确地说是面板的可变顺序。
例如,向用户显示 3 个不同的内容部分(这些是从 1 到 3 的面板)。但是,在设置中,他应该设置这些内容部分的显示顺序(例如,panel3 应该在顶部,panel1 在中间,panel2 在底部)。
我想到的唯一想法是使用组件绑定或某种不可见的排序数据列表,但这些是我宁愿避免的方法,因为它涉及太多变通方法。
解决方案
这在 JSF中实际上很容易。该框架使您能够将自己插入生命周期的不同渲染和构建事件中。因此,例如,您可以轻松地使用此功能在视图呈现并发送到浏览器之前对组件进行洗牌。
编码
这是一个p:panel
定义了五个组件的 XHTML 页面示例。每次重新加载页面时,组件都会被打乱并以不同的顺序显示。您可以轻松地调整它以按照您喜欢的顺序或根据某些配置设置显示它们;
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Shuffle test</title>
</h:head>
<h:body>
<h:panelGroup>
<p:panel header="First"/>
<p:panel header="Second"/>
<p:panel header="Third"/>
<p:panel header="Fourth"/>
<p:panel header="Fifth"/>
<f:event listener="#{shuffleBackingBean.onShuffle}" type="preRenderComponent" />
</h:panelGroup>
</h:body>
</html>
从f:event
标签的位置可以看出,我们将自己插入到preRenderComponent
parent 的阶段h:panelGroup
。这允许我们在该组件的渲染阶段之前接收事件。
@Named
@ViewScoped
public class ShuffleBackingBean implements Serializable {
public void onShuffle(ComponentSystemEvent event) {
final List<UIComponent> components = new ArrayList<>(event.getComponent().getChildren());
Collections.shuffle(components);
event.getComponent().getChildren().clear();
event.getComponent().getChildren().addAll(components);
}
}
上面的支持 bean 定义了onShuffle
方法,并且在调用时只是随机播放组件。如果您重新加载页面,组件会重新洗牌。
边注
对组件列表的副本执行 a 的原因shuffle()
是 JSF 使用了一个ChildrenList
基于ArrayList
. 该实现是拙劣的,并导致Collections.shuffle()
与IndexOutOfBoundsException
. 这只是解决这个问题。
替代解决方案
处理这个问题的另一种方法是依赖某些提供内置排序的组件或使用在h:panelGroup
组件上声明的绑定。这将允许您根据某些设置以编程方式填充此组件。但是,这会将大部分视图定义从 XHTML 文件中移出到 java 类中。如果您的面板中有很多子组件,它也会使事情稍微复杂化,如果它们彼此非常不同,则会使事情变得更加复杂。以编程方式定义所有这些可能非常麻烦。
结论
就个人而言,我更喜欢插入事件循环并仅移动或修改已在 XHTML 页面中定义的组件(根据上面的代码),因为这会将更多的视图定义移动到它所属的 XHTML 文件中。
推荐阅读
- android - Android XML:具有匹配父布局的 Android 中的垂直 Seekbar 无法正常工作
- java - cmake java 演示项目无法使用我的 MANIFEST.MF 创建“jar”
- c# - 类在控制器中没有无参数构造函数异常
- binary - 如何在 MIPS 机器代码中将负数转换/编码为立即数
- apache-kafka - 是否有与 AWS Kinesis Firehose 对应的 Kafka?
- html - HTML5 音频样式
- css - Bootstrap 4 - 跨列排列元素容器以具有相等的高度
- django - Django2.2 部分数据,除非指定端口(ERR CONTENT LENGTH MISMATCH)
- python-3.x - ElementNotVisibleException:消息:尝试通过 Selenium 和 Python 单击按钮时出现元素不可交互错误
- javascript - Javascript电话号码验证-错误消息擦除