好吧,这有点棘手,因为 html<input type="file">
任何更新后都会丢失其选择,并且真实模型对象(选择文件)FileUploadField
仅当post
事件发生。所以,即使我们添加AjaxEventBehavior
with onchange
事件进入我们的文件面板 - 用户选择文件后,它的模型将为空。
实际上,我们之前已经可以访问所选的文件了post
仅从js请求,您可以实现“保存”脚本,将已选择的文件保存在某个数组中,同时处理ajax更新,然后将它们设置回来,但这很乏味。
因此,解决此问题的另一种方法是仅在新添加的组件上处理更新,而不触及其他组件。
我会用RepeatingView
,因为我只需要在单击时生成新的 wicket idaddLink
而不是根据模型。代码如下(仔细阅读注释):
/* Method, which init your form */
private void init()
{
/* Container, which will hold all FileUploadFields,
as RepeatingView adds children to it's parent object. */
WebMarkupContainer container = new WebMarkupContainer("container");
/* We need DOM id for container component. */
container.setOutputMarkupId(true);
add(container);
final RepeatingView rv = new RepeatingView("dokumenteList");
container.add (rv);
/* We need to add all default model values by ourselfs for RepeatingView: */
for(EtdDokument doc : getListModel().getObject())
{
createDocumentRow(rv, doc);
}
final AjaxLink<String> addLink = new AjaxLink<String>("addDokument") {
@Override
public void onClick(AjaxRequestTarget target) {
final EtdDokument newValue...;
final EtdDokumentRowPanel r = createDocumentRow(rv, newValue);
...
/* This is it. We dynamicly adding created earlier component to markup.
This allows us to update this component via ajax. */
target.prependJavaScript(
"var item=document.createElement('div');" + //creating empty 'div' tag
"item.id='" + r.getMarkupId() + "'; " + // set markup id for this 'div'.
"Wicket.$('" + container.getMarkupId() + "').appendChild(item);" // add this 'div' as container child.
);
/* Added 'div' is still empty, but this update will replace
it, by real component's markup.*/
target.add(r);
}
};
add(addLink);
}
/* This method creates new instance of EDRowP (with random id) and adds
it to RepeatingView.
I have dropped the implementation of your headRow, but you can include it
into the EDRowPanel or implement something similar.
*/
private EtdDokumentRowPanel createDocumentRow( RepeatingView rv, EtdDokument doc )
{
EtdDokumentRowPanel row = new EtdDokumentRowPanel(rv.newChildId(), doc);
rv.add(row);
return row;
}
在标记中:
<form...>
...
<div wicket:id="container">
<div wicket:id="dokumenteList"></div>
</div>
<a href wicket:id="addDokument">Add</a>
....
</form>
对于小问题来说,这看起来太麻烦了,但我认为,没有更优雅的解决方案了(或者可能是我现在太困了,看不到它)。这应该有效。