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

时间:2012-07-04 08:12:20

标签: wicket textfield repaint

我正在制作一个教师创造问题的表格。一类问题是多项选择题。该表单有一个textArea,您可以在其中编写问题表达式,以及一个带有textFields的listView作为替代方案。

有一个按钮可以添加一个新的替代方案(添加一个新的textField),按下它时会重新绘制所有替代方案并添加一个新方法。现在问题出在这里:我希望listView中的文本字段中包含文本,以便在重绘后保留教师编写的文本,但我不知道如何使其成为可能(除了在每次重绘之前将值保存到数据库中) ,但这似乎是一个坏主意)。

这是我的MultipleChoiceQuestionPanel的代码,我希望它就足够了。

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);
    }
}

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:3)

来自Javadoc of ListView

  

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

     

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

这基本上就是这里发生的事情。对于ListView,您必须将setReuseItems设置为true。