gpt4 book ai didi

java - Wicket:带有 ListView 的 FileUploadField

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:22:52 25 4
gpt4 key购买 nike

  • 我有一个用于上传多个文件的页面。对于每个文件,用户必须指定类型和描述,这就是为什么我不能使用 MultiFileUploadField...所以我使用 RepeatingViewFileUploadField 在每个元素中以及我需要的其他两个字段。

  • 问题在于,无论何时单击“添加文件”按钮 (AjaxLink),已有文件的 FileUploadFields 都会重置为空。 ..

我能做什么?

这是 ListView(抱歉,它不是 RepeatingView,而是 ListView):

IModel<List<EtdDokument>> listModel = getListModel();
ListView<EtdDokument> dokumenteList = new ListView<EtdDokument>("dokumenteList", listModel) {

private static final long serialVersionUID = 1L;

@Override
protected void populateItem(ListItem<EtdDokument> item) {
final boolean showHeaders = ((getList() == null) || getList().size() == 0);

final WebMarkupContainer headRow = new WebMarkupContainer("headRow");
headRow.setVisible(showHeaders);
item.add(headRow);

EtdDokumentRowPanel etdDokumentRow = new EtdDokumentRowPanel("bodyRow", item.getModel());
item.add(etdDokumentRow);

}
};
dokumenteList.setReuseItems(true);
add(dokumenteList);

AjaxLink<Void> addLink = new AjaxLink<Void>("addDokument") {

private static final long serialVersionUID = 1L;

@Override
public void onClick(AjaxRequestTarget target) {
EtdConfiguration etdConfig = EtdConfigForm.this.getModelObject();
final EtdDokument newValue = new EtdDokument(etdConfig);
tempEtdDokumente.add(newValue);
target.addComponent(EtdConfigForm.this);
}
};
add(addLink);
  • EtdDokumentRowPanel 没有什么有趣的,我只是显示一个 FileUploadField,一个用于文件描述的 TextField 和一个 DropDownChoice 选择文档类型(我们自己的分类)。

最佳答案

好吧,这有点棘手,因为 html 的 <input type="file">在任何更新后丢失它的选择,以及 FileUploadField 的真实模型对象(选择的文件)仅在 post 时设置事件发生。所以,即使我们添加 AjaxEventBehavioronchange事件进入我们的文件面板 - 它的模型在用户选择文件后将为空。

实际上,我们可以在 post 之前访问所选文件仅从 js 请求,您可以实现“保存”脚本,将已选择的文件保存在某个数组中,同时处理 ajax 更新,然后将它们设置回去,但这很乏味。

因此,另一种解决此问题的方法是仅在新添加的组件上进行更新,不要触及其他组件。

我将使用 RepeatingView ,因为我只需要在单击 addLink 时生成新的 wicket id而不是根据模型。这是代码(仔细阅读评论):

/* 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>

对于小问题来说,这看起来太麻烦了,但我认为,没有比这更优雅的解决方案了(或者可能是我现在太困了,看不到它)。这应该有效。

关于java - Wicket:带有 ListView 的 FileUploadField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26604516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com