JSF页面中组件(面板)的可变顺序 [英] Variable order of components (panels) in JSF page

查看:45
本文介绍了JSF页面中组件(面板)的可变顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道JSF(或其任何框架,例如Primefaces)是否有可能在页面中显示可变的组件顺序,或更确切地说是面板.

I would like to know if there is a possibility in JSF (or any of its frameworks, such as Primefaces) to have a variable order of the components, or more precisely panels, that will be displayed in the page.

例如,向用户显示3个不同的内容部分(从1到3的面板).但是,在设置中,他应该设置这些内容部分的显示顺序(例如,panel3应该在顶部,panel1在中间,panel2在底部).

For example, a user is displayed 3 different content sections (these being panels from 1 to 3). However, in settings, he is supposed to set the order in which these content sections are displayed (say, panel3 should be at the top, panel1 in the middle, and panel2 at the bottom).

我想到的唯一想法是使用组件绑定或某种不可见的排序数据列表,但是我宁愿避免使用这些方法,因为它涉及太多的解决方法.

Only idea coming to my mind is to use component binding or some kind of an invisible sorted datalist, but those are approaches that I would rather avoid as it involves too many workarounds.

推荐答案

在JSF中,这实际上非常简单.该框架使您能够将自己插入不同的渲染并构建生命周期中的事件.因此,例如,您可以轻松地使用此功能在呈现视图并将其发送到浏览器之前对组件进行随机播放.

This is actually quite easy in JSF. The framework offers you the ability to plug yourself into the different rendering and build events of the life cycle. So you can, for example, easily use this functionality to shuffle components around before the view is rendered and sent to the browser.

这里是一个XHTML页面的示例,其中定义了五个 p:panel 组件.每次您重新加载页面时,这些组件都将被随机排列并以不同的顺序显示.您可以轻松地对此进行调整,以按照您喜欢的顺序或根据某些配置设置显示它们;

Here is an example of a XHTML page with five p:panel components defined. Each time you reload the page, the components will be shuffled and shown in a different order. You can easily adapt this to show them in an order you prefer or according to some configuration settings;

<?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 标记的位置可以看到,我们将自己插入父 h:panelGroup preRenderComponent 阶段>.这样一来,我们可以在该组件的呈现阶段开始之前接收事件.

As you can see from the placement of the f:event tag, we plug ourselves into the preRenderComponentphase of the parent h:panelGroup. This allows us to receive an event before it's time for the rendering phase of this component.

@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 方法,并且在调用时仅对组件进行了混洗.如果重新加载页面,则组件将重新组合.

The backing bean above defines the onShufflemethod and just shuffles the components around when called. If you reload the page, the components get re-shuffled.

对组件列表的副本执行 shuffle()的原因是,JSF使用基于 ArrayList ChildrenList 类.代码>.该实现被破坏,并导致 Collections.shuffle()崩溃,并出现 IndexOutOfBoundsException .可以解决该问题.

The reason for doing a shuffle() on a copy of the component list is that JSF uses a custom ChildrenList class that is based on ArrayList. The implementation is botched and causes Collections.shuffle() to crash with an IndexOutOfBoundsException. This just works around that issue.

处理此问题的另一种方法是依赖提供内置排序功能的某些组件,或使用在 h:panelGroup 组件上声明的绑定.这将允许您基于某些设置以编程方式填充此组件.但是,这会将大部分视图定义移出XHTML文件并移到Java类中.如果面板中有很多子组件,也会使事情稍微复杂化,并且如果它们彼此非常不同,则会使事情变得更加复杂.以编程方式定义所有内容可能很麻烦.

Another way of dealing with this would be to rely on some component that offers built-in sorting or use a binding declared on the h:panelGroup component. This would allow you to populate this component programmatically based on some setting. However, this moves much of the view definition out of the XHTML file and into a java class. It also complicates things slightly if you have a lot of sub-components in your panels and makes it even more complicated if they are very different from each other. Defining all that programmatically can be quite a hassle.

就个人而言,我更喜欢插入事件周期,而只是移动或修改XHTML页面中已经定义的组件(按照上面的代码),因为这会将更多视图定义移动到它所属的XHTML文件中.

Personally, I prefer plugging into the event cycle and just moving or modifying components already defined in the XHTML page (as per the code above), as this moves more of the view definition into the XHTML file where it belongs.

这篇关于JSF页面中组件(面板)的可变顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆