【问题标题】:How to add ajax close listener to my panel dynamically?如何动态地将 ajax 关闭侦听器添加到我的面板?
【发布时间】:2013-08-29 14:15:08
【问题描述】:

我动态创建我的面板,我也想动态添加 ajax 关闭侦听器,但对我不起作用。对于每个面板:

    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!!! "); 
        }
    }

监听器没有被调用。

【问题讨论】:

  • 您使用的是哪个版本的 primefaces?
  • Ajax4jsf 是 RichFaces 的子库(即那些 <a4j:xxx> 标签)。您没有在代码中的任何地方使用它。相反,您使用的是 PrimeFaces。请不要用[ajax4jsf]标记问题,谢谢。
  • 另外,不要在每篇文章的末尾抱怨“请帮助我,我卡住了”。它看起来如此愚蠢和不专业。 Just ask the question the smart way。我相应地编辑了你的帖子。

标签: ajax jsf primefaces


【解决方案1】:

您的具体问题是由于以下行引起的,

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>,您需要使用PrimeFaces 自己的AjaxBehavior,并让您的听众从PrimeFaces 自己的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 建议将它们作为支持bean 类的实例变量。对于设计和线程安全来说,这是一个非常糟糕的主意。它们应该在方法局部范围内获得,并且永远不能作为实例变量分配。

此外,您是否考虑过 <ui:repeat><c:forEach> 在循环中动态创建面板的目的?这最终会得到比这个烂摊子更干净和声明性的代码。

【讨论】:

  • 谢谢,它对我有用!我看看 .
【解决方案2】:

尝试使用 MethodExpression 而不是直接创建您的侦听器。在这种情况下,ClosePanelListener 应该是一个托管 bean。

 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);

【讨论】:

  • 感谢您的快速响应,但我已经尝试过 MethodExpression,但我收到了由“new AjaxBehaviorListenerImpl(me)”引起的错误。显然它来自构造函数,它需要两个参数。你有小费吗?
  • 在 primefaces 论坛“forum.primefaces.org/…”中查看此主题,用户 dmantil 发布了解决该问题的方法(重播发送“2010 年 12 月 7 日,04:37”)也许会有所帮助。顺便说一句,如果它没有解决您的问题,您不必接受答案。
  • 我更新了我的答案。这是 AjaxBehaviorListenerImpl 的 src,您可以查看构造函数中的这两个侦听器是如何处理的:code.google.com/p/primefaces/source/browse/primefaces/trunk/src/…
猜你喜欢
  • 1970-01-01
  • 2021-08-10
  • 2012-05-29
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多