概要

<s:iterator>と同等の機能を提供しますが、ループ変数のスコープを<r:foreach>の内側に限定します。

また、ローカル変数スコープタグでもあります。

タグの属性

  • var: ループ変数の名前。<s:iterator>のvarと同じです。
  • value: ループ対象となる値(Collection, Map, 配列)。<s:iterator>のvalueと同じです。
  • status: ループのステータスオブジェクトを保持する変数名。<s:iterator>のstatusと同じです。

タグのボディの扱い

タグのボディをJSPとしてレンダリングした結果をそのまま出力します。

サンプルコード

その1

  1. <%@ page pageEncoding="UTF-8"%>
  2. <%@ taglib uri="/struts-tags" prefix="s"%>
  3. <%@ taglib uri="/r42fw-tags" prefix="r"%>
  4. <r:foreach var="hoge" value="{1, 2, 3}">
  5. (hoge) = <s:property value="#hoge" />
  6. <%-- foreachローカル変数スコープタグでもある --%>
  7. <r:set-local var="moge" value="'abc'" />
  8. </r:foreach>
  9. (hoge) = <s:property value="(#hoge == null ? 'null' : #hoge)" />
  10. (moge) = <s:property value="(#moge == null ? 'null' : #moge)" />

実行結果

    (hoge) = 1
    (hoge) = 2
    (hoge) = 3

(hoge) = null
(moge) = null

その2

main.jsp

  1. <%@ page pageEncoding="UTF-8"%>
  2. <%@ taglib uri="/struts-tags" prefix="s"%>
  3. <%@ taglib uri="/r42fw-tags" prefix="r"%>
  4. <r:block>
  5. <r:set-local var="hoge" value="1" />
  6. (hoge in main.jsp) = <s:property value="#hoge" />
  7. <s:include src="./sub.jsp" />
  8. (hoge in main.jsp) = <s:property value="#hoge" />
  9. </r:block>

sub.jsp

  1. <%@ page pageEncoding="UTF-8"%>
  2. <%@ taglib uri="/struts-tags" prefix="s"%>
  3. <%@ taglib uri="/r42fw-tags" prefix="r"%>
  4. <r:foreach var="hoge" value="{1, 2, 3}">
  5. (hoge in sub.jsp) =<s:property value="#hoge" />
  6. </r:foreach>

main.jspの実行結果

(hoge in main.jsp) = 1

    (hoge in sub.jsp) = 1
    (hoge in sub.jsp) = 2
    (hoge in sub.jsp) = 3

(hoge in main.jsp) = 1

注意点

<r:foreach>はローカル変数スコープタグですが、 通常のプログラミング言語におけるforループとはブロックの扱いが異なることに注意する必要があります。

例えば、Javaのコードで言うところの

  1. for (...) {
  2. //ここではiはまだ「存在」していない
  3. int i = ...; //iを宣言する
  4. //これ以降、iは「存在」する
  5. }

このように記述したとき、変数iはループする度に毎回初期化されます。 一方で、<r:foreach>タグを使って次のように記述することは、

  1. <r:foreach ...>
  2. <r:set-local var="1" value="..." />
  3. </r:foreach>

Javascriptで言うところの (言語が入り混ってしまいすいません) このように記述することと同値です。

従ってローカル変数iは、ループする度に初期化されるわけではありません。

  1. (function() {
  2. for (...) {
  3. //JavascriptのスコープはJavaとは異なる。
  4. //2回目以降のループの場合、ここの時点でiは「存在」する。
  5. var i = ...; //iを宣言する
  6. ...
  7. }
  8. })();