Как добавить динамический динамик ajax для моей панели?
2 Samolo [2013-08-29 17:15:00]
Я динамически создаю свою панель, и я хочу динамически добавлять ajax close listener, но не работает для меня. Для каждой панели:
int u = _memosId.get(i);
Panel panel = (Panel)_application.createComponent(_context, "org.primefaces.component.Panel", "org.primefaces.component.PanelRenderer");
panel.setId("mymemo_" + String.valueOf(u));
panel.setHeader(_userNames.get(i));
panel.setClosable(true);
panel.setToggleable(true);
HtmlOutputText memo = new HtmlOutputText();
memo.setValue(_userMemos.get(i));
panel.getChildren().add(memo);
AjaxBehavior ajaxBehavior =(AjaxBehavior)_context.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
ajaxBehavior.addAjaxBehaviorListener(new ClosePanelListener());
ajaxBehavior.setTransient(true);
panel.addClientBehavior("close", ajaxBehavior);
_column1.addWidget(panel.getId());
getDashboard().getChildren().add(panel);
и слушатель моего класса:
private static class ClosePanelListener implements AjaxBehaviorListener
{
@Override
public void processAjaxBehavior(AjaxBehaviorEvent event) throws AbortProcessingException
{
System.out.println("----------->>>>>>>>>>AjaxListener CALLED!!! ");
}
}
Слушатель не вызывается.
ajax jsf primefaces
2 ответа
3 Решение BalusC [2013-08-30 19:10:00]
Ваша конкретная проблема вызвана тем, что следующая строка,
AjaxBehavior ajaxBehavior =(AjaxBehavior)_context.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
по существу создает <f:ajax>
, в то время как этот <p:panel>
закрытый прослушиватель действительно поддерживается только <p:ajax>
. Вы также можете увидеть его в сгенерированном HTML-выходе; Mojarra.ab()
(или любая специальная функция MyFaces в случае использования MyFaces вместо Mojarra) используется вместо PrimeFaces.ab()
.
Чтобы правильно создать <p:ajax>
, вам нужно использовать собственный AjaxBehavior
и позволить вашему слушателю простираться от собственного AjaxBehaviorListenerImpl
от AjaxBehaviorListenerImpl
:
import org.primefaces.component.behavior.ajax.AjaxBehavior;
import org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl;
AjaxBehavior ajaxBehavior = new AjaxBehavior();
public static class ClosePanelListener extends AjaxBehaviorListenerImpl
(обратите внимание, что я сменил вложенный класс от private
к public
, иначе вы можете столкнуться с проблемами видимости с некоторыми EL-объектами)
Не связанное с конкретной проблемой соглашение об использовании именования переменных _application
и _context
предполагает, что они содержатся как переменные экземпляра класса бэк-компонента. Это очень плохая идея по проектированию и безопасности потоков. Они должны быть получены в локальной области метода и никогда не должны быть назначены в качестве переменных экземпляра.
Кроме того, считали ли вы <ui:repeat>
или <c:forEach>
для самой цели динамического создания панелей в цикле? Это будет в гораздо более чистом и декларативном коде, чем этот беспорядок.
0 kaos [2013-08-29 17:47:00]
Попробуйте использовать методExpression вместо прямого создания вашего слушателя. В этом случае ClosePanelListener должен быть управляемым компонентом.
Application application = _context.getApplication();
ExpressionFactory ef = _context.getApplication().getExpressionFactory();
MethodExpression me = ef.createMethodExpression(_context.getELContext(),
"#{closePanelListenerBean.processAjaxBehavior()}", null, new Class[]{AjaxBehaviorEvent.class});
AjaxBehavior ajaxBehavior = new AjaxBehavior();
AjaxBehaviorListenerImpl ajaxBehaviorImpl = new AjaxBehaviorListenerImpl(me, me);
ajaxBehavior.addAjaxBehaviorListener(ajaxBehaviorImpl);
panel.addClientBehavior("close", ajaxBehavior);