1

3ページすべてでajax機能を使用する3ページフロー全体で情報を保持する必要があります。だからこれは私が構造を設計した方法です

1)アクションメソッド、Ajaxメソッド、および3ページに必要な属性を含む1つのビュースコープBean(@ViewScoped)

2)        Wizard.xhtml 
          |_  Step1.xhtml
          |_  step2.xhtml
          |_  step3.xhtml 

Wizard xhtmlには、ユーザーが現在操作しているページに基づいた条件付きレンダリングを備えたこれら3つのファセットが含まれています。したがって、基本的に、ステップ1からステップ2に移動するときに、wizard.xhtmlについて言及します。だから私の疑問は、Beanインスタンスがここにどのように住んでいるのかということです。フロー全体に存在しますか(存在する場合はパフォーマンスの問題が発生します)、それとも破棄されてから再作成されますか?

このアプローチを使用すると、すべてのページで値を保持できますが、これが本当に優れた設計アプローチであるかどうか、およびそれがテーブルにもたらす可能性のある影響/欠点を知りたいと思いました。前もって感謝します :)

4

2 に答える 2

2

ウィザード タイプのフローを構築するには、基本的に 2 つのオプションがあります。最初のオプションは、1 つのビュー内にすべてのステップを表示することです。もう 1 つは、ウィザードにステップがあるため、ビューの数を表示することです。

1 つのビュー内のすべてのウィザード手順

Xtreme Biker が正しく言及しているように、ビューを設計する最も自然な方法は、条件付きでレンダリングされたコンポーネントのすべてのステップを分離し<h:panelGroup>、別のウィザード ステップに入ったときに Bean のプロパティ currentStep を更新することです。

基本的なビューのセットアップ:

<h:panelGroup id="step1">
    <h:panelGroup rendered="#{bean.currentStep eq 1}">
        <ui:include src="step1.xhtml"/>
    </h:panelGroup>
</h:panelGroup>
...

含まれているページ (step2.xhtml):

...
<h:commandButton value="Back" action="#{bean.back}">
    <f:ajax execute="step2" render="step1 step2"/>
</h:commandButton>
<h:commandButton value="Forward" action="#{bean.forward}">
    <f:ajax execute="step2" render="step1 step2"/>
</h:commandButton>
...

バッキング Bean:

@ManagedBean
@ViewScoped
public class Bean implements Serializable {

    ...
    private int currentStep = 1;//getter+setter

    public String forward() {
        ...
        if(currentStep == 2) {
             doSomethingWithValues();
             currentStep++;
        }
        ...
    }

    public String back() {
        ...
        if(currentStep == 2) {
             clearNecessaryValues();
             currentStep--;
        }
        ...
    }

}

このアプローチは、カスタマイズされたコンテンツをビューに埋め込みたい場合に適しています。「標準」のアプローチに慣れている場合は、車輪を再発明してPrimefaces ライブラリの<p:wizard>タグを使用するのではなく、基本的に同じことを行います。

異なるビューでのすべてのウィザード ステップ

戻る/進むボタンを呼び出して別のビューに移動し、flash必要なデータを次のビューに転送するオブジェクトを使用してジョブを実行するたびに異なる結果を返す場合。

したがって、セットアップは次のようになります: wizard/step2.xhtml(ステップごとに 1 つのビュー) および 1 つのビュー スコープ Bean Bean

ビューの 1 つ (2 つ目のビュー)

...
<h:commandButton value="Back" action="#{bean.back}">
</h:commandButton>
<h:commandButton value="Forward" action="#{bean.forward}">
</h:commandButton>
...

バッキング Bean:

@ManagedBean
@ViewScoped
public class Bean implements Serializable {

    ...
    private int currentStep = 1;//getter+setter

    @ManagedProperty("#{flash}")
    private Flash flash;//getter+setter

    private Data step1Data;
    private Data step2Data;
    private Data step3Data;
    ...

    @PostConstruct
    public void init() {
        int step = Integer.parseInt(flash.get("newStep"));
        Data step1 = (Data)flash.get("step1");
        Data step2 = (Data)flash.get("step2");
        Data step3 = (Data)flash.get("step3");
        this.currentStep = step;
        this.step1Data = step1;
        this.step2Data = step2;
        this.step3Data = step3;
        ...
    }

    public String forward() {
        ...
        if(currentStep == 2) {
             doSomethingWithValues();
             currentStep++;
             flash.put("step", currentStep);
             flash.put("step1", step1Data);
             flash.put("step2", step2Data);
             return "wizard/step3?faces-redirect=true"
        }
        ...
    }

    public String back() {
        ...
        if(currentStep == 2) {
             clearNecessaryValues();
             currentStep--;
             flash.put("step", currentStep);
             flash.put("step1", step1Data);
             return "wizard/step1?faces-redirect=true"
        }
        ...
    }

}
于 2013-03-09T07:14:53.553 に答える
1

フローがajaxベースになる場合は、@ViewScopedBean を使用しても問題ありません。その種の Beanは、ナビゲーションの結果が返された場合にのみ破棄されるため、コンテンツを切り替える ajax 呼び出しが null または空の文字列値を返す限り、問題はありません。基本的に、コンポーネント レンダリング ベースのフローを使用し、それらを制御するために変数を使用する必要があります。

<h:outputPanel rendered="#{bean.screen eq 'first'}">
    //your first screen
</h:outputPanel>
<h:outputPanel rendered="#{bean.screen eq 'second'}">
    //your second screen
</h:outputPanel>
<h:outputPanel rendered="#{bean.screen eq 'third'}">
    //your third screen
</h:outputPanel>

タグ ハンドラーであり、コンポーネント自体の前に評価される<ui:include>ため、タグを使用して xhtml を含めることに注意する必要があります。したがって、それらの 1 つを上記のコンポーネントに入れると、レンダリングされるかどうかに関係なく、それらすべてが評価されます。私が以前に経験した同様の問題を見てください。

于 2013-03-08T08:51:09.297 に答える