forEach で古い値が残っちゃう

最近は勉強も兼ねてプライベートでも Teeda を触っております。
コレ面白いですね。html と Page クラス用意すればとりあえず動くんでサクサク感がやばい。
なんでもっと早くに知らなかったんだろう。改めて自分の情報収集力の無さに絶望した!


というわけで、また壁にぶちあたったのでエントリでも書くとします。
ファイルアップローダーみたいなものを作ってるわけですが、どうも forEach の部分で思い通りに動かず。
とりあえずソース。

public class FileInfoDto {
    int fileNo; // ファイル番号
    String fileName; // ファイル名

    // getter/setter は省略
}
public class UploaderPage {
    List<FileInfoDto> fileItems;
    int fileNo;
    String fileName;

    public void doUpload() {
        // アップロード処理
    }

    public void doDownload() {
        // ダウンロード処理
    }

    public void doDelete() {
        // 削除処理
    }
}
<head>
(〜いろいろ省略〜)
<script type="text/javascript">
    function setFileNo(name) {
        var hidden = name.substring(0, name.lastIndexOf(':'));
        var f = document['layoutChildBody:uploaderForm'];
        f.fileNo.value = f[hidden + ':fileNo-x'].value;
    }
</script>
</head>
<body>
<form id="uploaderForm" enctype="multipart/form-data">
<input id="fileNo" type="hidden" />
<table>
    <thead>
        (〜省略〜)
    </thead>
    <tbody id="fileItems">
        <tr>
            <td>
                <input id="doDownload" type="image" src="./img/download.png" onclick="setFileNo(this.name)" />
                <input id="doDelete" type="image" src="./img/delete.png" onclick="setFileNo(this.name)" />
                <input id="fileNo-x" type="hidden" />
            </td>
            <td><span id="fileName">ファイル名</span></td>
            (〜他省略〜)
        </tr>
    </tbody>
</table>
</form>
</body>

色々省略してますが、とりあえず上のようなソースを書いて動かしてみたのです。
ちなみに、これは一つのページ上でアップロード、ダウンロード、削除とか全部できるように作ってあります。


ここで、ファイルが何個か並んでる状態で削除処理を行おうと doDelete を呼び出すボタンを押すと、削除処理後にまたこの画面に戻ってファイルが1個消えることは画面上確認できるのですが、何故か fileNo が前の状態で残ってたりするんですよ。
わかりやすく言うと・・・

(削除前)
 ファイル番号 | ファイル名
                                                    • -
1 | ファイル1
                                                    • -
2 | ファイル2
                                                    • -
3 | ファイル3
                                                    • -
ここでファイル2を削除 (削除後) ファイル番号 | ファイル名
                                                    • -
1 | ファイル1
                                                    • -
2 | ファイル3
                                                    • -

この状態で、続けてファイル3を削除しようとするとファイル番号2は既に消えてるのでぬるぽが出たり/(^o^)\
画面をリロードするとちゃんと

 ファイル番号 | ファイル名
                                                    • -
1 | ファイル1
                                                    • -
3 | ファイル3
                                                    • -

期待する状態になってくれます。


なんとなーく、ファイル番号は input で持ってるから値が引き継がれちゃってるんだろうなとは思うんですが、これをどうやってクリアしたもんだか・・・。
doFinish() とか作っても直らないし、自分の知識量じゃ既に万策尽きました\(^o^)/
さぁ、どうしようか・・・。

動いたよ!

会社で仕事しながら調べていたら、id:yone098 さんの redirect forward - よねのはてな においてピンときたので、帰ってからソースを以下のように修正して動かしてみました。

public Class<?> doDelete() {
    // 削除処理

    return UploaderPage.class;
}

すると、、期待通りに動いた!
これだと forEach の外にある fileNo を別の変数名に変えなくてもうまいこと動いてくれました。
これからは自 Page に遷移する場合でも、void じゃなくて自分の Class を返した方がいいのかもしれませんね・・・。

上の解決方法は本質的な解決じゃないらしい

koichik 氏のコメントにより、また下記のように Page クラスを修正。

FileInfoDto[] fileItems;

public void doDelete() {
    // 削除処理
}

元のソースからは List から配列に変えただけ。
そして期待通り動きました。
Teeda 1.0.11 以前だと、forEach の中身が増減するような場合は配列で持たせた方がいい、ということですね・・・。