繰り返し

同じ処理を何回もさせることができます。forEach属性にオブジェクト集(コレクション)を指定することで、ディベロッパーは関連している要素の処理回数を決めます。便宜上、要素がforEach属性に指定される場合、その要素を繰り返し要素と呼びます。

以下の例でリスト項目は三回作成されます。集合を指定するのに、EL表記を使わなければなりません。

<listbox>
  <zscript>
  grades = new String[] {"Best", "Better", "Good"};
  </zscript>
  <listitem label="${each}" forEach="${grades}"/>
</listbox>

繰り返す方式はforEach属性の指定された値のタイプによって違います。

<listbox>
  <listitem label="${each}" forEach="grades"/>
</listbox>

each 変数

処理中、eachと呼ばれる変数は作成され、指定されたコレクションの項目に指定されます。上の例では最初の繰り返し処理の中で、eachにBestが指定されて、次にBetterが指定され、最後にGoodが指定されます。

each変数はEL表記とzscriptどちらを使っても参照することができます。each変数の値は一度定義されたら、ZKはそれを関連要素の処理が終わるまで保存します。

forEachStatus 変数

forEachStatus変数はorg.zkoss.ui.util.ForEachStatusのインスタンスです。現在の繰り返し処理についての情報を持っています。主に、forEach属性に指定された括弧でくくられた要素の項目を取得します。

以下の例では入れ子状態の繰り返しを使い、二つのリストボックスを生成します。

<hbox>
    <zscript>
classes = new String[] {"College", "Graduate"};
grades = new Object[] {
    new String[] {"Best", "Better"}, new String[] {"A++", "A+", "A"}
};
    </zscript>
    <listbox width="200px" forEach="${classes}">
        <listhead>
            <listheader label="${each}"/>
        </listhead>
        <listitem label="${forEachStatus.previous.each}: ${each}"
        forEach="${grades[forEachStatus.index]}"/>
    </listbox>
</hbox>

forEachStatus変数はEL表記とzscriptどちらを使っても参照することができます。.

イベントリスナ中のeachforEachStatus変数の使用方法

イベントリスナ中でforEachとforEachStatusを使うことは、コンポーネント作成段階[32]でのみ使用可能なので注意を払わなければなりません。こうして、以下の例は正しくありません。onClickリスナが呼び出されると、each変数が使えなくなります。

<window title="Countries" border="normal" width="100%">
          <zscript><![CDATA[    
          String[] countries = {    
                    "China", "France", "Germany", "United Kindom", "United States"};        
          ]]></zscript>    

          <hbox>    
                    <button label="${each}" forEach="${countries}"        
                              onClick="alert(each)"/> <!-- incorrect!! -->            
          </hbox>    
</window>

同じ段階(コンポーネント作成段階)で行われるので、ボタンのラベルは正確に指定されています。

また、イベントリスナ中でEL表記を使うことはできません。例えば、OnclickリスナはJavaコードではないので以下のコードは実行失敗してしまいます。(つまり、EL表記はzscript中で無視されます。)

<button label="${each}" forEach="${countries}"
                    onClick="alert(${each})"/> <!-- incorrect!! -->        

解決策: custom-attributes

each(とforEachStatus)のコンテンツをどこかに保存すれば問題は解決します。保存したコンテンツはリスナ実行中でも使用可能です。また、コンテンツはどこでも保存可能ですが、以下のようにするとわかりやすいです。

<window title="Countries" border="normal" width="100%">
          <zscript><![CDATA[    
          String[] countries = {    
                    "China", "France", "Germany", "United Kindom", "United States"};        
          ]]></zscript>    

          <hbox>    
                    <button label="${each}" forEach="${countries}"        
                    onClick="alert(self.getAttribute(&quot;country&quot;))">        
                              <custom-attributes country="${each}"/>            
                    </button>        
          </hbox>    
</window>

ボタンラベルのように、custom属性のプロパティはコンポーネント作成段階で処理され、そこでeachを使うことができます。eachはcustom属性に保存され、コンポーネントが存在する限り(又は、プログラム上で削除されなければ)なくなりません。



[32] コンポーネントのライフサイクルの章をご覧ください。