У меня две панели в калитке.
ParentPanel и
ChildPanel
Сценарий
ChildPanel является составной частью ParentPanel.
Каждый раз, когда на родительской панели запускается определенное событие, я хочу добавить определенный javascript в ChildPanel.
Рабочее решение
ParentPanel.java
public class ParentPanel extends Panel
{
private static final long serialVersionUID = 4306746527837380863L;
private final ChildPanel childPanel;
public ParentPanel(String aId, IModel<AnnotatorState> aModel)
{
super(aId);
model = aModel;
// initially the Child panel is empty. passing empty model
childPanel = new ChildPanel("child-container", Model.of());
childPanel.setOutputMarkupId(true);
add(childPanel);
}
@OnEvent
public void onClickText(RenderEvent aEvent)
{
LOG.trace("Event Fired");
IPartialPageRequestHandler iPartialPageRequestHandler = aEvent.getRequestHandler();
Integer someData = getSomeData();
childPanel.setDefaultModel(Model.of(someData));
//I am trying to add the child panel to the ajax target to ensure rerendering of child panel.
iPartialPageRequestHandler.add(childPanel);
}
}
ChildPanel.java
public class ChildPanel extends Panel
{
private static final long serialVersionUID = -3849226240909011148L;
private static final Logger LOG = LoggerFactory.getLogger(ChildPanel.class);
private IModel<Integer> model;
public ChildPanel(String aId, IModel<Integer> aModel)
{
super(aId);
model = (aModel);
}
@Override
public void renderHead(IHeaderResponse aResponse)
{
super.renderHead(aResponse);
model = (IModel<Integer>) getDefaultModel();
if (model == null)
return;
Integer someData = model.getObject();
String someJavascript = createSomeJavascript(someData);
log.debug("Rendering Updated UI with the JS: ", javascript);
aResponse.render(OnDomReadyHeaderItem.forScript(javascript));
}
}
По-видимому, renderHead() вызывается каждый раз, когда дочерняя панель добавляется в iPartialPageRequestHandler, и выполняет мою работу по обновлению пользовательского интерфейса при каждом событии, запускаемом в ParentPanel.
Проблема
Однако мне сказали, что это не очень хорошая практика. Поскольку в этом случае JS добавляется в renderHead(), то он попадает в исходный код страницы, что становится громоздким при отправке (больших) данных JSON. Необходимо найти хорошее место для присоединения JS к цели AJAX (возможно, render() или, возможно, лучше onRender() или onAfterRender()), только если это возможно/выполнимо в Wicket. Из-за моих ограниченных знаний я не могу предположить, как еще я могу реализовать сценарий. Любое другое (лучшее или возможное) решение приветствуется и приветствуется.
Спасибо.
Я изучил эти методы. Но я могу использовать их только в том случае, если у меня есть целевой объект ajax. Это приводит меня к вопросу, в какой функции я должен добавить javascript, чтобы он вызывался каждый раз, когда дочерняя панель добавляется в обработчик запросов. Я пытаюсь реализовать метод onRender или onAfterRender, но не могу получить ajaxTarget или iPartialPageRequestHandler, которые я могу использовать для вызова метода prependJavaScript.
Я почти уверен, что никогда не упоминал AjaxRequestTarget. Я имею в виду эти методы: ci.apache.org/projects/wicket/apidocs/8.x/org/apache/wicket/… и ci.apache.org/projects/wicket/apidocs/8.x/org/apache/wicket/…
Опять же, я не уверен, существуют ли они в Wicket 1.5.x или 6.x (которые вы отметили), хотя они определенно существуют в Wicket 7.x и 8.x.
Да, эти методы существуют, но могу ли я получить доступ к объекту IPartialPageRequestHandler в onRender(), чтобы я мог вызывать prependJavascript в этой функции?
Мне нужно переопределить функцию в ChildPanel, которая вызывается каждый раз, когда она перерисовывается из ParentPanel. А также должен быть способ получить доступ к объекту iPartialPageRequestHandler, чтобы я мог вызвать для него prependJavaScript(). Я только предполагаю, что мне поможет переопределение метода onRender() с помощью iPartialPageRequestHandler. Но я не уверен, существует ли он. Также это можно сделать другим способом, кроме простого переопределения метода.
Поскольку в ParentPanel уже есть ссылка на ChildPanel, нельзя ли решить эту проблему, просто введя свой собственный метод в ChildPanel и вызвав его из метода onClickText?
Если я это сделаю, то обновление страницы удалит javascript. Причина, по которой я ищу такую функцию, как onRender(), заключается в том, чтобы убедиться, что она выполняется также при обновлении страницы после нажатия кнопки. Вы можете сказать, что после нажатия кнопки и появления JS (пример графика javascript) в пользовательском интерфейсе ChildPanel я хочу сохранить его, даже при обновлении страницы, пока не будет нажата следующая кнопка. На следующей кнопке я снова хочу обновить Javascript на основе щелчка и изменить пользовательский интерфейс. Опять же, при обновлении пользовательский интерфейс (JavaScript) должен сохраняться.
Я храню данные в модели ChildPanel, поэтому при обновлении их можно использовать для использования того же javascript для визуализации того же пользовательского интерфейса, который был отображен при самом последнем щелчке.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я предполагаю, что проблема в том, что createSomeJavascript создает большой кусок кода?
Затем я бы реорганизовал его так, чтобы createSomeJavascript просто вызывал функцию, которую вы добавляете к компоненту с помощью JavaScriptResourceReference. Таким образом, в исходный код попадает лишь небольшая часть кода Javascript.
Например, поместите свой javascript во внешний файл следующим образом:
private static final ResourceReference JS_QM = new JavaScriptResourceReference( ClientPanel.class, "question.mark.js" );
@Override
public void renderHead( Component component, IHeaderResponse response )
{
super.renderHead( component, response );
response.render( JavaScriptReferenceHeaderItem.forReference( JS_QM, "question-mark" ) );
...
}
Как добавить функцию javascript в компонент с помощью JavaScriptResourceReference?
Если я реорганизую свою функцию так, как вы предложили, я все равно буду передавать большой кусок данных при вызове функции. Это функция рендеринга диаграмм, и ей нужны массивы данных для отображения в виде кривой обучения. Вам не кажется, что проблема останется прежней?
Ах (вы можете улучшить свой вопрос с помощью этой информации :). Если это ваша проблема, вы можете использовать библиотеку диаграмм, которая может динамически извлекать данные (например, через ajax), и использовать Behaviour с URL-адресом обратного вызова, который доставит вам данные. Просто передайте URL-адрес обратного вызова и позвольте JS получить свои собственные данные.
Возможно, проверьте это для вдохновения: github.com/adessoAG/злые диаграммы
Сейчас вы добавляете HeaderItem (т. е. фрагмент, который помещается в
<head>) при каждом рендеринге. Если вместо этого вы хотите выполнить определенный фрагмент JS до/после добавления компонента, но не более того, вам следует взглянуть на методыIPartialPageRequestHandler.prependJavaScriptиIPartialPageRequestHandler.appendJavaScript.