4

Primefaces コンポーネントを使用して動的ブレッドクラムを Web アプリに追加したいと考えています。ブレッドクラムに項目をプッシュするモデルを作成して、そのリンクの 1 つがたどられたときに末尾のリンクが削除されるようにしました。これはほとんどのシナリオで機能しますが、ブラッドクラムが期待どおりに動作しないことがあります。基本的に、ランディング ページを追跡するために、preRenderViewナビゲート可能な各ページにリスナーを追加し、モデル更新ロジックをセッション スコープ Bean に実装しました。

  <f:event type="preRenderView" listener="#{bcb.onRenderView}" />
  <f:attribute name="pageName" value="ThisPage" />

リスナーはページ名を属性として受け取り、外部コンテキストから完全な URL (クエリ文字列を含む) を取得します。これらの情報は、 から作成された一意の ID とともに、モデルにプッシュUIViewRootされる を構築するために使用されます。BreadCrumbItem

public void onRenderView(ComponentSystemEvent evt) {
  UIViewRoot root = (UIViewRoot)evt.getSource();
  final String reqUrl = FacesUtils.getFullRequestURL();
  String pageName = (String) evt.getComponent().getAttributes().get("pageName");
  if(pageName != null) {
    model.push(new BreadCrumbItem(root.createUniqueId(), pageName, reqUrl));
  } else {
    model.reset();
  }
}

モデルのpush()およびreset()メソッドは次のように実装されます。

/**
 * When a link is pushed on the bread crumb, the existing items are analyzed
 * and if one is found to be equal to the pushed one, the link is not added
 * and all the subsequent links are removed from the list.
 * 
 * @param link
 *            the link to be added to the bread crumb
 */
public void push(BreadCrumbItem link) {
    boolean found = removeTrailing(link);
    if(!found) {
        addMenuItem(link);
    }
}

/**
 * Reset the model to its initial state. Only the home link is retained.
 */
public void reset() {
    BreadCrumbItem home = new BreadCrumbItem();
    removeTrailing(home);
}

このアプローチは実現可能ですか?ライフサイクル リスナーを活用する必要なく、ページ ナビゲーションを追跡するためのより良い方法を提案できますか? どうもありがとうございました。

4

1 に答える 1

3

私は自分の Web アプリ用に独自のものを実装しました。私の場合は、p:breadCrumbボタンを使用して実装されているため、コンポーネントを使用しませんでした。

基本的に@SessionScoped、スタック (ナビゲーション スタック) を含む Bean があり、ブレッドクラムにあるすべての URL とそれぞれのパラメーターを格納します。ビュー ( xhtml ) 部分は、スタックの格納された URLp:buttonを持つ要素で構成されます。outcome

urlに移動すると、対応する Beanf:event type="preRenderView"が呼び出され (実行している方法で)、Bean は URL からパラメーターを取得します。その後、Bean 自体ではなくスタックに確立されます@ViewScoped。 url と params のみが破棄されます)。

ブレッドクラムの戻るボタンをクリックした場合、ボタンのインデックスを示す追加のパラメーターを送信します。そのインデックスに基づいて、宛先 Bean は、そのようなビューを回復しようとしていることを認識しているため、ナビゲーション スタックにそのビュー パラメータを要求し、ナビゲーション スタックはその後にある navegables を削除します。

少し時間がかかりましたが、完全に機能しています。幸運を。

編集

現在のナビゲーション状態を保存するためにセッション スコープを使用する場合は注意してください。開いているすべてのタブに影響を与えるため、エンド ユーザーが 1 つのタブでのみアプリケーションを使用することを期待しない限り、おそらくそれは望ましくありません。とにかく、一般的なユーザビリティ ガイドラインでは、パンくずリストのナビゲーション パスではなくカテゴリを使用する必要があるとされています ( HTTP はステートレスであり、履歴自体はブラウザーによって保持されます)。そのため、少なくともビューに別の URL を使用している場合、動的ブレッドクラムはもはや意味がありません。

于 2013-01-22T15:34:03.103 に答える