Java 使用带有复选框和DB数据的无状态表单

Java 使用带有复选框和DB数据的无状态表单,java,wicket,stateless,Java,Wicket,Stateless,我想做一个页面,显示我的网站的哪些用户具有当前的“角色”。每个用户都有一组角色,一个角色影响0~n个用户 我将显示一个包含用户姓名的基本列表,以及每个用户的复选框。然后是提交按钮。 提交表单时,它将从所选用户中删除角色 大多数时候,它工作得很好。但是,如果DB的数据在页面加载和表单提交之间发生更改,则会出现问题 如果我们陷入这种情况,它会删除错误用户的角色 我尝试过不同的方法,现在我用的是这样的方法: import java.util.LinkedList; import java.util.L

我想做一个页面,显示我的网站的哪些用户具有当前的“角色”。每个用户都有一组角色,一个角色影响0~n个用户

我将显示一个包含用户姓名的基本列表,以及每个用户的复选框。然后是提交按钮。
提交表单时,它将从所选用户中删除角色

大多数时候,它工作得很好。但是,如果DB的数据在页面加载和表单提交之间发生更改,则会出现问题

如果我们陷入这种情况,它会删除错误用户的角色

我尝试过不同的方法,现在我用的是这样的方法:

import java.util.LinkedList;
import java.util.List;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.list.AbstractItem;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;


public class Test extends WebPage {
    private static final long serialVersionUID = 1L;


    /**
     * An item used to link the checkbox to the Database Object
     */
    public static class Item {
        private boolean selected = false;
        private int num;

        public Item(final int num) { this.num = num; }
        public final boolean isSelected() { return selected; }
        public final int getNum() { return num; }
        public final void setSelected(boolean selected) { this.selected = selected; }
        public final void setNum(int num) { this.num = num; }
    }



    public Test(final PageParameters params) {
        // This list will hold items we display
        final List<Item> values = new LinkedList<Item>();

        // Our stateless form
        final StatelessForm<Void> form = new StatelessForm<Void>("form") {
            private static final long serialVersionUID = 1L;

            @Override
            protected void onSubmit() {
                // On submit, we check our items to see which ones are selected
                String toDelete = "";

                for (final Item it : values) {
                    if (it.selected) {
                        toDelete += it.getNum() + ", ";
                    }
                }

                System.out.println(toDelete);
            }
        };
        add(form);

        form.add(new Button("submit"));

        // We retrieve our data from the Database
        final List<Integer> things = getFromDatabase();

        // We print them
        final RepeatingView rp = new RepeatingView("li");
        form.add(rp);

        for (int num : things) {
            final AbstractItem item = new AbstractItem(rp.newChildId());
            rp.add(item);

            // We create our holder
            final Item it = new Item(num);
            values.add(it);

            item.add(new Label("name", num));

            // We use the property of our holder as model
            item.add(new CheckBox("checkbox", new PropertyModel<Boolean>(it, "selected")));
        }
    }



    /**
     * Simulate a fetch from the database by swapping our data at each requests
     */
    public static int num = 0;

    private static List<Integer> getFromDatabase() {
        final List<Integer> list = new LinkedList<Integer>();

        if (num++ %2 == 0) {
            list.add(1);
            list.add(2);
        }
        else {
            list.add(2);
            list.add(1);
        }

        return list;
    }
}
import java.util.LinkedList;
导入java.util.List;
导入org.apache.wicket.markup.html.WebPage;
导入org.apache.wicket.markup.html.basic.Label;
导入org.apache.wicket.markup.html.form.Button;
导入org.apache.wicket.markup.html.form.CheckBox;
导入org.apache.wicket.markup.html.form.form;
导入org.apache.wicket.markup.html.list.AbstractItem;
导入org.apache.wicket.markup.repeater.RepeatingView;
导入org.apache.wicket.model.PropertyModel;
导入org.apache.wicket.request.mapper.parameter.PageParameters;
公共类测试扩展网页{
私有静态最终长serialVersionUID=1L;
/**
*用于将复选框链接到数据库对象的项
*/
公共静态类项{
选择的私有布尔值=false;
私有整数;
公共项(final int num){this.num=num;}
公共最终布尔值isSelected(){return selected;}
public final int getNum(){return num;}
公共最终void setSelected(布尔选择){this.selected=selected;}
公共最终void setNum(int num){this.num=num;}
}
公共测试(最终页面参数参数){
//此列表将保存我们显示的项目
最终列表值=新建LinkedList();
//我们的无国籍形式
最终无状态表单=新的无状态表单(“表单”){
私有静态最终长serialVersionUID=1L;
@凌驾
受保护的void onSubmit(){
//在提交时,我们检查我们的项目以查看哪些项目被选中
字符串toDelete=“”;
对于(最终项目it:值){
如果(它被选中){
toDelete+=it.getNum()+“,”;
}
}
System.out.println(toDelete);
}
};
添加(表格);
添加(新按钮(“提交”);
//我们从数据库中检索数据
final List things=getFromDatabase();
//我们把它们打印出来
最终RepeatingView rp=新RepeatingView(“li”);
表格.增补(rp);
for(int num:things){
final AbstractItem item=新的AbstractItem(rp.newChildId());
rp.add(项目);
//我们创造我们的持有者
最终项目it=新项目(数量);
添加(it);
添加(新标签(“名称”,编号));
//我们使用持有人的财产作为模型
添加(新复选框(“复选框”,新属性模型(“选中”));
}
}
/**
*通过在每次请求时交换数据,模拟从数据库获取数据
*/
公共静态int num=0;
私有静态列表getFromDatabase(){
最终列表=新的LinkedList();
如果(num++%2==0){
增加第(1)款;
增加(2);
}
否则{
增加(2);
增加第(1)款;
}
退货清单;
}
}
以及:


我通过在每次请求页面时交换值来模拟不断变化的数据库

如果我选择“1”并按submit,它会删除“2”

我知道为什么,但我不知道如何修复它

解决这个问题的最好方法是采用如下方式:

<input type="checkbox" name="toDelete[]" value="<the_id>" />
<input type="checkbox" name="toDelete[]" value="<the_id>" />
etc.
但我不知道如何使用Wicket,在互联网上也找不到任何东西=/


所以是的。。有什么例子/想法吗?

Hi Tiller,你看过wicket-library.com/wicket-examples-6.0.x/index.html上的wicket示例表、列表和重复视图吗?这是一个很好的起点(看看重复部分)。我发现下载wicket示例(从wicket主页)并在您的机器上运行它们很有用。这样,您就可以逐步了解代码并了解示例的工作原理。它们几乎只使用statefull页面:)使用要删除的行的唯一标识符(如主键)而不是“num”的列表索引如何?是的,我想问,但我不想假设任何事情。num指的是什么?您没有使用任何IModel-s包装数据。Wicket正在构建页面并序列化页面中的所有内容,以及您的数据。页面构造函数通常只调用一次,因此数据不会被更新。包装数据是LoadableDetachableModel,因此可以对其进行升级。
<input type="checkbox" name="toDelete[]" value="<the_id>" />
<input type="checkbox" name="toDelete[]" value="<the_id>" />
etc.