java - 构建可重用的 Wicket 组件

标签 java forms architecture wicket

所以这不是一个非常笼统的问题,但我希望有人能给我一些架构方面的建议,以便我可以构建以下可重用的 wicket 组件。

这是skitch上的粗略草图:

https://skitch.com/cmagnollay/8sn2s/multitextform

我知道,画得很棒吧?所以本质上,这个表单组件(我认为这是正确使用的类)将用于在表单上添加用户定义的输入数量。当用户点击 TextInputField 旁边的 - 按钮时,它会删除该 inputField。当他们点击 + 按钮时,会添加一个新的空白字段。显然,当用户单击按钮时,组件将需要使用 AJAX 来更新组件,但我的问题是如何构建它。这是一节课吗?两个(一个用于整个组件,一个用于带有 - 按钮的输入字段),我应该使用哪些类来执行此操作?我希望对象尽可能通用以促进重用。这是我目前所拥有的:

public class MultiTextInput<T> extends FormComponent<List<T>>
{
    private static final long serialVersionUID = 1L;

    private final String removeInputButtonName = "removeInputButton";
    private final String addInputButtonIdName = "addInputButton";

    private int numInputs = 1;
    private List<TextField<T>> inputFieldList = new ArrayList<TextField<T>>();

    public MultiTextInput(String id, IModel<T> model) 
    {
        super(id);

        inputFieldList.add(new TextField<T>("input1", model));

        add(inputFieldList.get(0));
        addAddInputFieldMarkup();
    }

    /**
     * Adds an "add" button.
     */
    private void addAddInputFieldMarkup()
    {
        Button addInputButton = new Button(this.addInputButtonIdName + numInputs);
        addInputButton.add(new AjaxFormComponentUpdatingBehavior("onclick"){

            private static final long serialVersionUID = 1L;

            @Override
            protected void onUpdate(AjaxRequestTarget target) 
            {
                numInputs++;

                inputFieldList.add(new TextField<T>("input" + numInputs));

                target.add(MultiTextInput.this);
            }

        });
    }

    /**
     * Adds a "remove" button.
     */
    private void addRemoveInputFieldMarkup()
    {
        Button removeInputButton = new Button(this.removeInputButtonName + numInputs);
        removeInputButton.add(new AjaxFormComponentUpdatingBehavior("onclick"){

            private static final long serialVersionUID = 1L;

            @Override
            protected void onUpdate(AjaxRequestTarget arg0)
            {
                // TODO Auto-generated method stub

            }

        });
    }


}

正如我所说,我只是想习惯于考虑制作 Wicket 组件。我在 OO 方面有很多经验,但在 wicket 方面并不特别。感谢您的帮助和指导!

最佳答案

我想实现所需行为的最简单方法是使用由 List 支持的 ListView。在按下添加/删除按钮后重新加载。

这里是一段代码乱写(未测试)

public abstract class MultiTextPanel<T> extends Panel {

public MultiTextPanel(String id, IModel<ArrayList<T>> model) {
    super(id, model);

    final Form<ArrayList<T>> multiTextForm = new Form<ArrayList<T>>("multiTextForm", model);
    add(multiTextForm);

    final ListView<T> listView = new ListView<T>("listView", model) {

        @Override
        protected void populateItem(final ListItem<T> item) {
            // TODO Auto-generated method stub
            TextField<T> textField = new TextField<T>("textField", item.getModel());
            add(textField);

            AjaxSubmitLink removeButton = new AjaxSubmitLink("removeButton", multiTextForm) {

                @Override
                protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                    multiTextForm.getModelObject().remove(item.getModelObject());
                    target.addComponent(multiTextForm);
                }

                @Override
                protected void onError(AjaxRequestTarget target, Form<?> form) {
                    //errors should be ignored, we shoudlnt validate in our form, so this shouldnt happen anyway
                    multiTextForm.getModelObject().remove(item.getModelObject());
                    target.addComponent(multiTextForm);
                }

            };              
            add(removeButton);

        }

    };
    add(listView);

    AjaxSubmitLink addButton = new AjaxSubmitLink("addButton", multiTextForm) {

        @Override
        protected void onError(AjaxRequestTarget target, Form<?> form) {
            //errors should be ignored, we shoudlnt validate in our form, so this shouldnt happen anyway
            multiTextForm.getModelObject().add(createNewT());
            target.addComponent(multiTextForm);
        }

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form form) {
            multiTextForm.getModelObject().add(createNewT());
            target.addComponent(multiTextForm);
        }
    };
    add(addButton);



}

public abstract T createNewT();}

基本的 html:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.sourceforge.net/" xml:lang="en" lang="en">
<wicket:panel>
    <form wicket:id="multiTextForm">
        <wicket:container wicket:id="listView">
            <input type="text" wicket:id="textField" />
            <a wicket:id="removeButton">-</a>
        </wicket:container>
    </form>
    <a wicket:id="addButton">+</a>
</wicket:panel>

我为此做的唯一特别的事情是在 ListView 周围放置一个表单,这样我们就可以在我们创建的面板内提交(在这个阶段很可能不需要验证,应该在保存屏幕的表单)。

此实现的缺点是您将始终重新加载完整的表单,因此会产生大量开销。仅添加/删除了 1 行,但重新呈现了 n(-/+)1 行。

关于java - 构建可重用的 Wicket 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10337049/

相关文章:

java - Stream.skip 行为与无序终端操作

jquery如何获取表单元素类型、名称和值

java - Spring MVC表单提交,在同一页面填充

audio - Java音频转换器api

java - 使用多个类时未定义构造函数

java - 生成一个频率的单个周期?

php - MVC - 用户输入验证 : controller, 模型或两者

python - Django 提供过时的表单验证选项

architecture - 企业、系统和应用程序架构(最佳实践?)

c - 'C' 项目架构指南的建议?