如何在Facelets中使用简单的for循环重复输出文本而无需使用模型?

25

如何使用JSF中的标准标签(ui:,h:等)重复输出某些内容?换句话说-如何在JSF中执行与下面的PHP代码相当的操作?我想立即利用 ui:repeat ,但它需要集合-我只有数字。

for ($i = 0; $i < 10; $i++) {
    echo "<div>content</div>";
}
2个回答

46

JSF 2.3+

如果您已经使用JSF 2.3+,则可以使用<ui:repeat>标签的begin/end属性。

xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
...
<ui:repeat begin="1" end="10">
    <div>content</div>
</ui:repeat>

JSF 2.2-

如果您还没有升级到JSF 2.3,则可以使用<c:forEach>代替(确实,将JSTL与JSF混用有时会受到批评,但在您的情况下,这不会造成任何影响,因为您似乎想要“静态”创建视图;它不依赖于任何动态变量):

xmlns:c="http://java.sun.com/jsp/jstl/core"
...
<c:forEach begin="1" end="10">
    <div>content</div>
</c:forEach>

或者创建一个EL函数来为<ui:repeat>创建一个虚拟数组:

package com.example.util;

public final class Functions {

    private Functions() {
        //
    }

    public static Object[] createArray(int size) {
        return new Object[size];
    }
}

该标签库注册在/WEB-INF/util.taglib.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
    version="2.0">
    <namespace>http://example.com/util/functions</namespace> 
    <function>
        <function-name>createArray</function-name>
        <function-class>com.example.util.Functions</function-class>
        <function-signature>Object[] createArray(int)</function-signature>
    </function>
</facelet-taglib>

并且被使用如下

xmlns:util="http://example.com/util/functions"
...
<ui:repeat value="#{util:createArray(10)}">
    <div>content</div>
</ui:repeat>

@BalusC,您认为将JSTL混合到JSF Web应用程序中怎么样?我遇到了一些人的意见认为这不是一个好的方法。 - marioosh
2
可以混合使用,但需要注意的是JSTL在视图构建时运行,而JSF在视图渲染时运行。如果您打算将JSTL用于视图渲染时间目的,则不好。或者当您打算在已经存在JSF组件/属性用于相同目的时使用JSTL时,也是不好的。在这种特殊情况下,您无法使用JSF组件,并且似乎也不会在视图渲染时使用它(否则您真的会有一个集合),因此应该没问题。 - BalusC
@BalusC提出的增强请求已被关闭,因为它已被另一个请求复制:http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1102。希望看到ui:repeat得到改进的所有人都应该跟随此链接,注册java.net,并投票支持此请求。自BalusC最初提出请求以来已经过去了一年多时间,等待时间太长了! - Mr. Lance E Sloan
1
@LS:如果您正在使用OmniFaces,请查看of:createArray()of:createIntegerArray()函数:https://showcase-omnifaces.rhcloud.com/showcase/functions/Arrays.xhtml - BalusC
哇,太棒了。这正是我所需要的。 - Dan Torrey
显示剩余4条评论

15

由于需要一个集合,您可以在后端Bean中创建一个集合(包含与您要输出div的数量相同的元素):

public class MyBean {
  private List list = new ArrayList<Integer();

  { ... populate the list with numbers, for example ... }

  public List getList() {
     return list;
  }
 ...
}

然后:

<ui:repeat value="#{myBean.list}" var="item">
  <div>content</div>
</ui:repeat>

..这将输出与list属性大小相同数量的div。


是的,但它需要在类中生成列表。我考虑过像PHP一样简单的东西 ;) - marioosh
这是正确的答案。ui:repeat是JSF安全的方式来执行JSTL的c:foreach。 - Calabacin
是的,毫无疑问这是最好的方法。 - Rob Grant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接