У меня есть простая форма Wicket, которая позволяет пользователям выбирать некоторые данные, а затем загружать ZIP-файл (сгенерированный на лету), содержащий то, что они просят. В настоящее время метод onSubmit()
кнопки формы выглядит примерно так:Какой самый простой способ реализовать загрузку фона в Wicket?
public void onSubmit() {
IResourceStream stream = /* assemble the data they asked for ... */ ;
ResourceStreamRequestTarget target = new ResourceStreamRequestTarget(stream);
target.setFileName("download.zip");
RequestCycle.get().setRequestTarget(target);
}
Это работает, но, конечно, запрос останавливается там, и это невозможно отобразить любую другую обратную связь с пользователем.
Что бы я хотел иметь, это что-то вроде типичной «Запрошенная вами загрузка [NAME] должна начинаться автоматически. Если нет, нажмите эту ссылку». В идеале, все еще отображается одна и та же страница, поэтому пользователь может сразу же выбрать некоторые другие данные и загрузить их.
Я предполагаю, что это возможно сделать с помощью классов Ajax от Wicket, но мне удалось избежать использования их до сих пор, и мне это не сразу становится очевидным. Какой у меня самый быстрый выход?
Обновлено в ответ от Зератулом, ниже: что я закончил с что-то вроде этого:
class MyDownloader extends AbstractAjaxBehavior {
private final MyForm form;
MyDownloader(MyForm form) {
this.form = form;
}
void startDownload(AjaxRequestTarget target) {
target.addComponent(myForm);
target.appendJavascript("window.location.href='" + getCallbackUrl() + "'");
}
@Override
public void onRequest() {
try {
ResourceStreamRequestTarget streamTarget = form.getStreamTarget();
form.info(/* some status message */);
getComponent().getRequestCycle().setRequestTarget(streamTarget);
catch (SomeException e) {
form.error(e.getMessage());
}
}
}
class MyForm extends Form {
private final MyDownloader myDownloader;
private final Object myModel;
MyForm(Object aModel) {
super("myForm");
myModel = aModel;
myDownloader = new MyDownloader(this);
add(myDownloader);
add(/* form components */);
add(new AjaxButton("download", new Model<String>("Download"), this) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
myDownloader.startDownload(target);
}
});
add(new FeedbackPanel("feedback"));
}
ResourceStreamRequestTarget getStreamTarget() throws SomeException {
return /* target based on form input */;
}
}
Это чувствует себя немного шаткий, но это, кажется, работает.
Это выглядит так, как будто это должно решить проблему, а загрузка часть делает работу, но, к сожалению, это не расскажите мне о том, как реально обновить страницу - в этом примере предлагается добавить компоненты к AjaxRequestTarget, но неясно, какова цель на самом деле или где находятся эти компоненты. –
Хорошо, понял это - просто нужно было добавить прилагаемую форму к цели. Weird API, но он работает. Благодарю. –
@DavidMoles Вот как все AJAX обрабатывается в Wicket: структура передает экземпляр «AjaxRequestTarget» в ваш код, и вам нужно добавить все компоненты, которые вы хотите повторно отобразить. – biziclop