2

パネルを動的に作成し、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!!! "); 
        }
    }

リスナーは呼び出されません。

4

2 に答える 2

3

次の行が原因で、具体的な問題が発生します。

AjaxBehavior ajaxBehavior =(AjaxBehavior)_context.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);

は本質的に を作成しますが<f:ajax>、この<p:panel>クローズ リスナーは実際には によってのみサポートされ<p:ajax>ます。生成された HTML 出力でも確認できます。Mojarra.ab()(または、Mojarra の代わりに MyFaces を使用している場合は、MyFaces 固有の関数) が代わりに使用されていPrimeFaces.ab()ます。

を適切に作成するには、代わりに PrimeFaces own を使用し、リスナーを PrimeFaces own から拡張できるよう<p:ajax>にする必要があります。AjaxBehaviorAjaxBehaviorListenerImpl

import org.primefaces.component.behavior.ajax.AjaxBehavior;
import org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl;
AjaxBehavior ajaxBehavior = new AjaxBehavior();
public static class ClosePanelListener extends AjaxBehaviorListenerImpl

(ネストされたクラスを から に変更したことに注意してくださいprivatepublicそうしないと、一部の EL 実装で可視性の問題が発生する可能性があります)


具体的な問題とは関係なく、変数の命名規則は、それらがバッキング Bean クラスのインスタンス変数として保持されること_application_context示唆しています。これは、設計とスレッドの安全性に関して非常に悪い考えです。これらはメソッド ローカル スコープで取得する必要があり、インスタンス変数として割り当てないでください。

さらに、ループ内でパネルを動的に作成することを検討したことがありますか<ui:repeat>? <c:forEach>これは、この混乱よりもはるかにクリーンで宣言的なコードになります。

于 2013-08-30T16:10:28.327 に答える
0

リスナーを直接作成する代わりに、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);
于 2013-08-29T14:47:09.287 に答える