Wicket:重新绘制文本字段并保留用户输入

Wicket:重新绘制文本字段并保留用户输入,wicket,textfield,repaint,Wicket,Textfield,Repaint,我在做一个表格,老师在上面提问。一类问题是多项选择题。表单有一个文本区域,您可以在其中编写问题公式,还有一个列表视图,其中包含备选方案的文本字段 有一个按钮可以添加一个新的备选方案(添加一个新的文本字段),当按下该按钮时,它会重新绘制所有备选方案并添加一个新的备选方案。现在问题来了:我希望listView中已经包含文本的文本字段在重新绘制后保留老师编写的文本,但我不知道如何实现这一点(除了在每次重新绘制之前将值保存到数据库中,但这似乎是个坏主意) 这是我的MultipleEchoiceQuest

我在做一个表格,老师在上面提问。一类问题是多项选择题。表单有一个文本区域,您可以在其中编写问题公式,还有一个列表视图,其中包含备选方案的文本字段

有一个按钮可以添加一个新的备选方案(添加一个新的文本字段),当按下该按钮时,它会重新绘制所有备选方案并添加一个新的备选方案。现在问题来了:我希望listView中已经包含文本的文本字段在重新绘制后保留老师编写的文本,但我不知道如何实现这一点(除了在每次重新绘制之前将值保存到数据库中,但这似乎是个坏主意)

这是我的MultipleEchoiceQuestionPanel的代码,我希望它足够了

public class MultiChoiceQuestionPanel extends QuestionPanel {

    private List<Alternative> alternatives;

    @SpringBean
    private AlternativeRepository alternativeRepository;

    public List<Alternative> getAlternatives(){
        return alternatives;
    }

    public MultiChoiceQuestionPanel(String id, MultipleChoiceQuestion q){
        super(id, q);

        final WebMarkupContainer parent = new WebMarkupContainer("alternativesContainer");
        parent.setOutputMarkupId(true);
        add(parent);
        parent.add(new Label("AnswerLabel", "Svar"));

        q.setAlternatives(alternativeRepository.findByMultipleChoiceQuestion(q));
        alternatives = q.getAlternatives();
        Form form = new Form("addForm");
        form.add(new ListView<Alternative>("alternatives", alternatives) {
            @Override
            protected void populateItem(final ListItem<Alternative> alternativeListItem) {
                alternativeListItem.add((TextField<String>) new TextField<String>("alternative", new AlternativeModel(alternativeListItem.getModelObject())).setRequired(true).setType(String.class));
                Form form = new Form("removeForm");
                form.add(new AjaxSubmitLink("remove") {
                    @Override
                    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                        Alternative selected = alternativeListItem.getModelObject();
                        alternativeRepository.delete(selected);
                        getAlternatives().remove(selected);
                        target.addComponent(parent);
                    }
                });
                alternativeListItem.add(form);
                add(alternativeListItem);
            }
        });

        AjaxSubmitLink a = new AjaxSubmitLink("add") {
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                Alternative alternative = new Alternative();
                MultipleChoiceQuestion mcq = (MultipleChoiceQuestion) getQuestion();
                alternative.setSequenceNumber(mcq.getAlternatives().size());
                alternative.setMultipleChoiceQuestion((MultipleChoiceQuestion) getQuestion());
                alternativeRepository.save(alternative);
                getAlternatives().add(alternative);
                target.addComponent(parent);
            }
        };
        a.setDefaultFormProcessing(false);
        form.add(a);
        parent.add(form);
    }
}
公共类MultiChoiceQuestionPanel扩展了QuestionPanel{
私人名单备选方案;
@春豆
私人代理代理代理代理代理代理代理;
公共列表getAlternations(){
返回备选方案;
}
公共MultiChoiceQuestionPanel(字符串id,MultipleChoiceQuestionQ){
super(id,q);
最终WebMarkupContainer父项=新的WebMarkupContainer(“备选容器”);
parent.setOutputMarkupId(true);
添加(父级);
添加(新标签(“应答标签”、“Svar”);
q、 设置备选方案(alternativeRepository.findByMultipleChoiceQuestion(q));
备选方案=q.getAlternations();
表格=新表格(“添加表格”);
添加(新列表视图(“备选方案”,备选方案){
@凌驾
受保护的void populateItem(最终列表项替代列表项){
add((TextField)new TextField(“alternative”,new AlternativeModel(alternativeListItem.getModelObject())。setRequired(true)。setType(String.class));
形式=新形式(“移除形式”);
添加(新的AjaxSubmitLink(“删除”){
@凌驾
提交时受保护的void(AjaxRequestTarget目标,表单){
Alternative selected=alternativeListItem.getModelObject();
替代存储。删除(选中);
getAlternations().remove(已选择);
target.addComponent(父级);
}
});
alternativeListItem.add(表格);
添加(可选列表项);
}
});
AjaxSubmitLink a=新的AjaxSubmitLink(“添加”){
@凌驾
提交时受保护的void(AjaxRequestTarget目标,表单){
备选方案=新备选方案();
多回音问题mcq=(多回音问题)getQuestion();
alternative.setSequenceNumber(mcq.getAlternatives().size());
alternative.setMultipleChoiceQuestion((MultipleChoiceQuestion)getQuestion());
替代存储。保存(替代);
getAlternations().add(可选);
target.addComponent(父级);
}
};
a、 setDefaultFormProcessing(false);
表格.加入(a);
添加(表格);
}
}
感谢您的帮助。

来自:

警告:虽然可以在表单中嵌套ListView,但必须设置 将setReuseItems属性设置为true以进行验证工作 对。默认情况下,setReuseItems为false,具有以下效果 该ListView用新实例替换所有子组件。想法 这背后的原因是,您总是呈现新的数据,并且作为人 通常使用ListView显示只读列表(至少是这样) 我们认为),这是良好的默认行为

但是, 在渲染开始之前替换组件,搜索 这些组件的特定消息在替换为时失败 其他情况。另一个问题是“错误”的用户输入被保留为 (临时)组件的实例数据。因为这些组件是 被新的数据替换后,您的用户将永远不会看到错误的数据 setReuseItems为false

这就是这里发生的事情。您必须将ListView的ReuseItems设置为true。

来自:

警告:虽然可以在表单中嵌套ListView,但必须设置 将setReuseItems属性设置为true以进行验证工作 对。默认情况下,setReuseItems为false,具有以下效果 该ListView用新实例替换所有子组件。想法 这背后的原因是,您总是呈现新的数据,并且作为人 通常使用ListView显示只读列表(至少是这样) 我们认为),这是良好的默认行为

但是, 在渲染开始之前替换组件,搜索 这些组件的特定消息在替换为时失败 其他情况。另一个问题是“错误”的用户输入被保留为 (临时)组件的实例数据。因为这些组件是 被新的数据替换后,您的用户将永远不会看到错误的数据 setReuseItems为false


这就是这里发生的事情。您必须将ListView的ReuseItems设置为true。

这似乎产生了一个新问题。添加新的文本字段效果很好,但我的删除按钮现在的行为很奇怪。无论我按哪个删除按钮,都是最后一个文本字段的文本消失,而不是我删除的文本字段中的文本。有什么解释/建议说明原因吗?@LeoSundholm这似乎是因为a)您不刷新ListView,只刷新某些ListItems,b)您不使用列表模型。您可以尝试将您的ListView构建为新的ListView(“备选方案”),新的PropertyModel(“备选方案”))这似乎产生了一个新问题。添加新的文本字段效果很好,但我的“删除”按钮运行正常