在没有 PropertyModel 的情况下在 Wicket 中保存数据

Saving Data in Wicket without PropertyModels

我正在尝试使用 Wicket 和 OrientDB 构建 Web 应用程序。我试图避免 writing/maintaining 将每个 Class 顶点表示为 POJO(如 ORM)的平面 Java class。相反,我将顶点本身一直发送到 Web 层。我通过以下方式访问属性:

vertex.getProperty("propertyName");

意思是属性本身不是Vertex的成员变量,因此不能通过正常的方式访问getters/setters。我 运行 遇到了 Wicket 的一个问题,因为许多组件都依赖于 "PropertyModel" 样式的实现,您在其中传入一个代表您正在使用的 class 的成员变量之一的模型, 数据存储在该成员变量中。

我有这个 DataView,它可以将顶点的属性提取到 Label 和 TextField 中。

public VertexViewer(final PageParameters pageParameters, OrientVertex vertex)
    this.vertex = vertex;
    this.properties = this.vertex.getProperties();

    List<String> keyList = new ArrayList<>();
    keyList.addAll(this.vertex.getPropertyKeys());

    final DataView<String> propertiesView = new DataView<String>("properties", new ListDataProvider<>(keyList)) {
        @Override
        protected void populateItem(Item item) {

            String key = item.getModelObject().toString();
            item.add(new Label("property_name", key));
            item.add(new TextField<String>("edit_field", new Model<String>(properties.get(key).toString())));
        }
    };
    add(propertiesViewer);
}

和HTML:

<wicket:extend>
    <div wicket:id="properties" style="display: table-row;">
        <div wicket:id="property_name" style="display: table-cell;"></div>
        <input wicket:id="edit_field" type="text" style="display: table-cell;"/>        
    </div>
</wicket:extend>

这完全符合我的要求,但是有人对我如何保存 TextFields 中正在更改的数据有任何建议吗?我不能像通常在 Form 上那样使用成员变量的模型,因为我永远不知道 what/how 许多属性将位于顶点中。我会以完全错误的方式解决这个问题吗?非常感谢任何帮助。

看看https://github.com/OrienteerDW/wicket-orientdb。 这个库的开发者也创造了 https://issues.apache.org/jira/browse/WICKET-5623,但是这个改进并没有得到太多的支持。如果您认为有需要,请随时为它投票。

因此,经过多次试验和错误(主要是错误)后,我发现了一种模式可以解决 Wicket 的 NoSQL 缺陷,并且不涉及手动创建成员变量来制作模型。

我从 vertex.getProperties() 获取了 Map<String, Object>,然后创建了它的副本。

private Map<String, Object> realProperties = baseVertex.getProperties();
private Map<String, Object> dummyProperties = new HashMap<>();
dummyProperties.putAll(realProperties);

这允许我使用 dummyProperties 中的值作为模型来存储数据。

List<String> keyList = new ArrayList<>();
keyList.addAll(getDummyProperties().keySet());

final DataView<String> propertiesView = new DataView<String>("properties", new ListDataProvider<>(keyList)) {
        @Override
        protected void populateItem(Item item) {

            String key = item.getModelObject().toString();
            item.add(new Label("property_name", key));
            item.add(new TextField<String>("edit_field", new PropertyModel<String>(getDummyProperties(), key)));
        }
};

从那里,我将 DataView 放在一个带有 AjaxButton 的表单上,该按钮通过一些复杂的循环将 TextFields 中的潜在新值与原始值进行比较。

AjaxButton saveButton = new AjaxButton("saveButton") {
        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            super.onSubmit(target, form);
            Map<String, Object> changedProperties = new HashMap<>();
            // for each entry in the dummy values linked via PropertyModel to the TextField input
            for (Map.Entry<String,Object> dummyEntry : getDummyProperties().entrySet()) {
                // for each entry in the
                for (Map.Entry<String,Object> realEntry : baseVertex.getProperties().entrySet()) {
                    // if the keys match
                    if (dummyEntry.getKey().equals(realEntry.getKey())) {
                        // if the value has changed
                        if (!dummyEntry.getValue().equals(realEntry.getValue())){

                            // value in textField differs from value in database
                            changedProperties.put(dummyEntry.getKey(),dummyEntry.getValue());
                        }
                    }
                }
            }

            DBWorker worker = new DBWorker();
            // perform the update
            worker.updateVertex(recordID, changedProperties);
            // pull the fresh vertex out and pass it to the page again
            setResponsePage(new VertexViewer(new PageParameters(), new CustomVertex(worker.getVertexByID(recordID))));
       }
};

这最终会根据旧值评估新值,将新值写回数据库,拉回新顶点并调用接受更新顶点作为参数的新 ViewerPage。

这按预期工作,对属性 vertex/number 的 class 是通用的,并且使我不必为每个顶点 类 维护 ORM 样式 class .