我有一个预览按钮。当用户按下预览时,表单会在新选项卡上提交以显示包含表单数据的 pdf 文件。
我使用自定义 SubmitLink 来做到这一点
提交资源链接
public abstract class SubmitResourceLink extends SubmitLink implements IResourceListener {
private final IResource resource;
@Override
public final void onResourceRequested() {
Attributes a = new Attributes(RequestCycle.get().getRequest(), RequestCycle.get().getResponse(), null);
resource.respond(a);
}
在形式上实现
new SubmitResourceLink("previewBtn", form, new JasperReportsResource() {
private static final long serialVersionUID = -2596569027102924489L;
@Override
public byte[] getData(Attributes attributes) {
return control.getExportPreviewByteStream(estimateModel.getObject());
}
}) {
private static final long serialVersionUID = 1L;
@Override
protected String getTriggerJavaScript() {
String js = super.getTriggerJavaScript();
js = "document.getElementById('" + form.getMarkupId() + "').target='_blank';" + js;
return js;
}
@Override
public void onSubmit() {
form.add(AttributeModifier.append("target", Model.of("_blank")));
processInputs(form);
onResourceRequested();
}
}.setDefaultFormProcessing(false);
当我按下预览时,会打开一个新选项卡。但是当我输入任何ajax组件(例如:AutoCompleteTextField)时,ajax响应数据xml:
<ajax-response><redirect>....</redirect></ajax-response>
并刷新页面。现在,我想在按下预览后,我仍然正常使用当前的表单。
谢谢。
最佳答案
这是由 Wicket 中的“陈旧页面保护”引起的。
第一次单击在新选项卡/窗口中打开相同的页面实例。这会增加页面的 renderCount
计数器,即它说“此页面已呈现 N 次”。
Wicket 中的链接看起来像 ?2-1.ILinkListener-component~path
.这里'2'是页面ID,'1'是页面渲染计数。
所以 tab1 中的链接有 renderCount 'N',而 tab2 中的链接 - 'N+1'。
单击 tab1 中的链接将失败,并显示 StalePageException,它告诉 Wicket“用户正在尝试使用页面的过时版本。请呈现页面的最新版本,以便用户可以重试”。
需要这种保护是因为用户可能会在 tab3 中执行许多操作,例如替换用于替换/隐藏用户想要在 tab1 中单击的链接的面板。如果没有这样的保护,Wicket 要么会失败
ComponentNotFoundException 尝试单击链接时,如果链接/按钮位于中继器中并且中继器已更改其在 tab2 中的项目,则更糟糕的情况可能会执行错误的操作。
要解决您的问题,您应该在 tab2 中打开一个新页面实例,即它提交表单但在 onSubmit()
中做类似 setResponsePage(getPage().getClass())
的事情.这样它就不会重新渲染当前页面实例 N+1 次。
关于ajax - 如果在使用 target=_blank 提交表单后使用 ajax,则刷新 Wicket 页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30609615/