5

Java EE 6 でアプリケーションを作成し、ユーザー インターフェイスに Primefaces 3.4.1 を使用しています。

私はそのようなものを持っています。

genericPage.xhtml

<ui:composition template="mainApplicationTemplate.xhtml" [...]>
    <p:tabView id="tabView" dynamic="false"cache="false">
        <p:tab id="tab1" title="Tab 1">
            <h:form id="form1">
                ...
            </h:form>
        </p:tab>
        <p:tab id="tab1" title="Tab 1">
            <h:form id="form2">
                ...
            </h:form>
        </p:tab>
    </p:tabView>
<ui:composition >

child1.xml

<ui:composition template="genericPage.xhtml" ...>
    <ui:param name="actionBean" value="#{actionBeanA}"/>
</ui:compisition>

child2.xml

<ui:composition template="genericPage.xhtml" ...>
    <ui:param name="actionBean" value="#{actionBeanB}"/>
</ui:compisition>

その背後にある考え方は、child1.xhtml と child2.xhtml が同じ jsf コードを共有し、すべてが genericPage.xhtml に含まれているが、バックエンド Bean が異なる (「actionBean」によってパラメータ化されている) ということです。

これまでのところ、それは非常にうまく機能しています。<p:ajax/>要素内に ui パラメータを入れると複雑になります。

バックエンド Bean から、アクティブなタブをプログラムで更新し、他のタブはそのままにしておく必要があります。そのためには、アクティブなタブをアクション Bean に格納する必要があります。特定の外部イベントが発生すると、アクション Bean はアクティブなタブを更新します。

その他の要因により、次の点に注意してください。

  • dynamic="true"で設定できませんtabView
  • の周りにグローバル フォームtabViewを配置できないため、「activeIndex」プロパティ (アプリケーションの別の部分で行っている) を使用してアクティブなタブを管理することはできません。

私がしたいこと

この問題を解決するには、要素のtabChangeイベントを使用します。tabView

<p:tabView id="tabView" dynamic="false"cache="false">
        <p:ajax event="tabChange" listener="#{actionBean.listen}"
        <p:tab id="tab1" title="Tab 1">
            <h:form id="form1">
                ...
            </h:form>
        </p:tab>
        <p:tab id="tab1" title="Tab 1">
            <h:form id="form2">
                ...
            </h:form>
        </p:tab>
    </p:tabView>

アクションビーン

@Named
@WindowScoped
public class ActionBeanA implements Serializable{
    public void listen(TabChangeEvent event){
        ...
    }

}

うまくいかないこと

私がそれをすると、エラーが発生します

Target Unreachable, identifier 'actionBean' resolved to null: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'actionBean' resolved to null

これは、<p:ajax>要素がアクション Bean に渡されていないため、何が何であるかがわからないことを示しているようactionBeanです。

ただし、そのようなリスナーメソッドのシグネチャを変更すると

<p:ajax event="tabChange" listener="#{actionBean.listen(anything)}"

バックエンド Bean を次のように変更します。

public void listen(TabChangeEvent event){
    System.out.println(event.toString());
}

そうすることで、ターゲットに到達できないエラーは発生しませんが、listen メソッドで null ポインター例外が発生します (「何か」に値を割り当てていないため)。これは、この場合、<p:ajax/>要素が何が何でactionBeanあるかを認識しており、Bean でメソッドを呼び出すことができていることを示しています。

質問

どうすればこの問題を回避できますか? タブ変更イベントで、バックエンド Bean に新しいアクティブなタブを送信できるようにしたいと考えています。

4

2 に答える 2

6

私もこの問題を抱えていて、Primefaces Issue Trackerで解決策を見つけました:投稿#20で解決策が見つかりました

要約すると、これはPrimefacesの既知の問題です。セミフィックスはリリース3.4.2にあり、コードにいくつかの変更が必要です。現時点では:

public void listen(TabChangeEvent event){
    System.out.println(event.toString());
}

これは機能しません。コードを次のように変更する必要があります。

public void listen(AjaxBehaviorEvent event){
    System.out.println(event.toString());
}

そして、特定の方法を使用する必要がある場合TabChangeEventは、キャストを行う必要があります(TabChangeEvent)event

課題トラッカーでステータスが修正されているため、永続的な解決策としてこれが必要になる場合があります。

于 2013-01-23T14:29:11.663 に答える
-1

値とメソッド式の処理には違いがあります。後者の場合、少し後でパラメータを使用できるようにする必要があります - Facelet コンテキストで。

パラメーターの値を facelet コンテキストに含めるには、パラメーター値の定義を<f:metadata>タグ内に配置するだけです。

また、<f:metadata>タグは常にタグの直接の子である必要があることに注意してください。そのため、次の<f:view>ようにします。

template.xhtml

<f:view ....>
    <ui:insert name="metadata"/>
    ....
</f:view>

childPage.xhtml

<ui:composition template="/WEB-INF/template.xhtml">
    <ui:define name="metadata">
        <f:metadata>
            <ui:param name="actionBean" value="#{actionBeanA}"
        </f:metadata>
    </ui:define>
</ui:composition>

これを行った後、回避策なしで元の方法でリスナー属性を使用でき、template.xhtmlメソッドは常に適切なイベント型パラメーターで呼び出されます。

于 2013-04-08T14:08:28.663 に答える