[英]Stateless ModalDialog in Wicket
How can I create a stateless ModalDialog using Wicket?如何使用 Wicket 创建无状态的ModalDialog ?
I tried the following code, but it results in an error.我尝试了以下代码,但它会导致错误。 The error doesn't occur when removing the
getStatelessHint()
overrides, but that would make it stateful.删除
getStatelessHint()
覆盖时不会发生错误,但这会使其成为有状态的。 If it's not possible, would it be possible with the deprecated ModalWindow ?如果不可能,是否可以使用已弃用的ModalWindow ?
HTML: HTML:
<!DOCTYPE html>
<html>
<head>
<style>
.modal-dialog { border-radius: 5px; }
.modal-dialog .modal-dialog-content { display: flex; flex-direction: column; }
.modal-dialog-overlay.current-focus-trap .modal-dialog-content { resize: both; }
.modal-dialog .modal-dialog-form { margin: 0; padding: 0; overflow: hidden; flex: 1; display: flex; flex-direction: column; }
.modal-dialog .modal-dialog-header { border-radius: 5px 5px 0px 0px; background: #ffb158; margin: 0; padding-top: 4px; text-align: center; }
.modal-dialog .modal-dialog-body { flex: 1; overflow-y: auto; padding: 20px; }
.modal-dialog .modal-dialog-footer { padding: 5px; }
</style>
</head>
<body>
<a wicket:id="openModalLink">Open modal</a>
<div id="window" wicket:id="window"></div>
<wicket:fragment wicket:id="modalContentFragment">
<h1>Modal Dialog</h1>
<a wicket:id="closeModalLink">Close modal</a>
</wicket:fragment>
</body>
</html>
Java: Java:
package org.example.modaltest;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalDialog;
import org.apache.wicket.extensions.ajax.markup.html.modal.theme.DefaultTheme;
import org.apache.wicket.markup.html.GenericWebPage;
import org.apache.wicket.markup.html.panel.Fragment;
public class ModalPage extends GenericWebPage<Void> {
public ModalPage() {
ModalDialog window = new ModalDialog("window");
window.add(new DefaultTheme());
window.setMarkupId("window");
window.setOutputMarkupId(true);
add(window);
Fragment modalContentFragment = new Fragment(ModalDialog.CONTENT_ID, "modalContentFragment", this);
window.setContent(modalContentFragment);
modalContentFragment.setOutputMarkupId(true);
AjaxLink<Void> closeModalLink = new AjaxLink<Void>("closeModalLink") {
@Override
public void onClick(AjaxRequestTarget target) {
target.add(window);
ModalDialog window1 = (ModalDialog) findPage().get("window");
window1.close(target);
}
@Override
protected boolean getStatelessHint() {
return true;
}
};
closeModalLink.setOutputMarkupId(true);
modalContentFragment.add(closeModalLink);
AjaxLink<Void> openModalLink = new AjaxLink<Void>("openModalLink") {
@Override
public void onClick(AjaxRequestTarget target) {
ModalDialog window1 = (ModalDialog) findPage().get("window");
window1.open(target);
}
@Override
protected boolean getStatelessHint() {
return true;
}
};
add(openModalLink);
}
}
Error in Browser:浏览器中的错误:
Access Denied.
拒绝访问。 You do not have access to the page you requested.
您无权访问您请求的页面。 Return to home page
返回首页
Java Exception: Java 异常:
16:34:16.382 [http-nio-8080-exec-4] WARN o.a.w.c.r.h.ListenerRequestHandler - behavior not enabled; ignore call. Behavior org.apache.wicket.ajax.markup.html.AjaxLink$1@5a149041 at component [AjaxLink [Component id = closeModalLink]]
16:34:16.386 [http-nio-8080-exec-4] WARN RequestCycleExtra - ********************************
16:34:16.390 [http-nio-8080-exec-4] WARN RequestCycleExtra - Handling the following exception
org.apache.wicket.core.request.handler.ListenerInvocationNotAllowedException: Behavior rejected interface invocation. Component: [AjaxLink [Component id = closeModalLink]] Behavior: org.apache.wicket.ajax.markup.html.AjaxLink$1@5a149041
at org.apache.wicket.core.request.handler.ListenerRequestHandler.invoke(ListenerRequestHandler.java:276)
at org.apache.wicket.core.request.handler.ListenerRequestHandler.invokeListener(ListenerRequestHandler.java:222)
at org.apache.wicket.core.request.handler.ListenerRequestHandler.respond(ListenerRequestHandler.java:208)
at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:902)
at org.apache.wicket.request.RequestHandlerExecutor.execute(RequestHandlerExecutor.java:63)
at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:283)
at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:254)
at org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:276)
at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:207)
at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:306)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:407)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
16:34:16.390 [http-nio-8080-exec-4] WARN RequestCycleExtra - ********************************
Problem is the following: Stateless links create a new page for each request.问题如下:无状态链接为每个请求创建一个新页面。 That new page does not know, that the modal dialog was opened previously.
该新页面不知道先前打开了模式对话框。 Thus the request to the nested closeModalLink is rejected, as it is not currently visible.
因此,对嵌套 closeModalLink 的请求被拒绝,因为它当前不可见。
You'll have to transport the information about opening the dialog via the request url.您必须通过请求 url 传输有关打开对话框的信息。 Eg your closeModalLink could add a parameter to its request via #updateAjaxAttributes(), which is checked on creation of the new page and automatically opens the dialog if requested.
例如,您的 closeModalLink 可以通过#updateAjaxAttributes() 向其请求添加一个参数,该参数在创建新页面时进行检查,并在请求时自动打开对话框。
Here is what @svenmeier tried to explain:这是@svenmeier 试图解释的内容:
opened
then pre-open the dialog at page creation time, so that any components/behaviors inside it are reachable in the following requestsopened
,则在页面创建时预先打开对话框,以便在以下请求中可以访问其中的任何组件/行为open
link to set the stateopen
的链接中添加一个额外的参数来设置 statepublic class ModalPage extends GenericWebPage<Void> {
public ModalPage(PageParameters parameters) {
super(parameters); // 1
ModalDialog window = new ModalDialog("window");
window.add(new DefaultTheme());
window.setMarkupId("window");
window.setOutputMarkupId(true);
add(window);
if (!parameters.get("mdOpened").isNull()) { // 2
window.open(null);
}
Fragment modalContentFragment = new Fragment(ModalDialog.CONTENT_ID, "modalContentFragment", this);
window.setContent(modalContentFragment);
modalContentFragment.setOutputMarkupId(true);
AjaxLink<Void> closeModalLink = new AjaxLink<Void>("closeModalLink") {
@Override
public void onClick(AjaxRequestTarget target) {
target.add(window);
ModalDialog window1 = (ModalDialog) findPage().get("window");
window1.close(target);
}
@Override
protected boolean getStatelessHint() {
return true;
}
};
closeModalLink.setOutputMarkupId(true);
modalContentFragment.add(closeModalLink);
AjaxLink<Void> openModalLink = new AjaxLink<Void>("openModalLink") {
@Override
public void onClick(AjaxRequestTarget target) {
ModalDialog window1 = (ModalDialog) findPage().get("window");
window1.open(target);
}
@Override
protected boolean getStatelessHint() {
return true;
}
// 3
@Override
public void updateAjaxAttributes(AjaxRequestAttributes attributes) {
attributes.getExtraParameters().put("mdOpened", "true");
}
};
add(openModalLink);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.