読者です 読者をやめる 読者になる 読者になる

Challenge Java EE !

Java EEを中心に趣味や仕事における開発メモを書いています。

PrimeFacesのCommandLinkでajax属性を悩ましく感じたケース

PrimeFaces 画面遷移 ConfirmDialog

PrimeFacesは非常に便利なコンポーネントが揃っていますが、たまにハマります。
今日ハマったのは、CommandLink(CommandButtonも多分同じですが)とダイアログ周りの動きです。

以前に書いた「PrimeFacesでManaged Bean内の判定結果に応じてダイアログの表示有無を制御をする方法」で、リンクをクリックした場合にManagedBeanの内部状態によって表示ダイアログを切り替える、ことをやりました。

今回もベースとなるシチュエーション(DataTable内のCommandLink)は同じで、やりたい処理は「リンクをクリックしてダイアログが出る場合もあるし、そのままCommandLinkのactionを実行して画面遷移する場合もある」という割と単純なものです。

が、PrimeFacesを触った方はわかると思いますが、CommandButtonやCommandLinkはajax属性がtrue(これがデフォルト)だと画面遷移ができません。これ自体、意外と最初にハマるのですが(^^;

なので、画面遷移する際は

  • ajax属性をfalseにして使う
  • redirectを使う

のが良いとされています(PrimeFacesのUsers GuideドキュメントのFAQ No.6とか)

今の開発では基本的に前者の方針を取っているのですが、今回やろうとしていることは

「リンクをクリックしてダイアログが出る場合もあるし、そのままCommandLinkのactionを実行して画面遷移する場合もある」

なので

  • ダイアログを出すためにはajax=trueじゃないといけない
  • 画面遷移するためにはajax=falseじゃないといけない

という矛盾がありました。試しにプログラム内でajaxをtrue/falseとスイッチしたりしましたが駄目でした(^^;

解決方法は「redirectを使う」しかなさそうで以下のような書き方をしました。

JSFxhtml

<p:commandLink id="lnkEdit" value="編集" ajax="true"
    actionListener="#{xxxBean.権限があるのか確認するメソッド(xxxList.xxx)}"
    action="#{xxxBean.画面遷移するメソッド()}"
    oncomplete="handleEditDialog(xhr, status, args)"/>
                        
                       
<script type="text/javascript">
    function handleEditDialog(xhr, status, args) {
        if(!args.hasAuth){
            accessDlg.show();
         }
    }
</script>

ManagedBean(CDIの)

public void 権限があるのか確認するメソッド(XXXXX xxx){
    boolean hasAuth = false;
        
    //中略 ~権限があるかチェックなど~ 
        
    RequestContext context = RequestContext.getCurrentInstance();
    context.addCallbackParam("hasAuth", hasAuth);
}
public String 画面遷移するメソッド(){

    RequestContext context = RequestContext.getCurrentInstance();
    Map<String,Object> map = context.getCallbackParams();
    boolean auth = (boolean)map.get("hasAuth");
    if(!auth){
        return null;
    }
        
    return "./画面遷移先ページ" + "?faces-redirect=true";
}

上記記述で、明細のリンクをクリックして
f:id:kikutaro777:20130306211342j:plain
ManagedBeanで権限チェック処理とか実行して、権限がなければ以下のようにダイアログ表示して、権限があれば、そのまま編集画面に進む、みたいな挙動が実装できました。
f:id:kikutaro777:20130306211346j:plain

以下のPrimeFaces Community Forumで全く同じことを質問している人がいたため助かりました(^^;
JSF Navigation and AJAX

redirectを普段使わないので、「矛盾してるの、どーやるの!」と地味にハマりました。

にほんブログ村 IT技術ブログへ
にほんブログ村
にほんブログ村 IT技術ブログ Javaへ
にほんブログ村