32

ページ上のdatatableを使用しており、バインディング属性を使用してバッキングBeanにバインドしています。これは私のコードです:-

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.prime.com.tr/ui">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
            <h:form prependId="false">

                <h:dataTable var="item" value="#{testBean.stringCollection}" binding="#{testBean.dataTable}">
                    <h:column>
                        <h:outputText value="#{item}"/>
                    </h:column>
                    <h:column>
                        <h:commandButton value="Click" actionListener="#{testBean.action}"/>
                    </h:column>
                </h:dataTable>

            </h:form>

    </h:body>
</html>

これは私の豆です:-

package managedBeans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.html.HtmlDataTable;

@ManagedBean(name="testBean")
@ViewScoped
public class testBean implements Serializable {

    private List<String> stringCollection;

    public List<String> getStringCollection() {
        return stringCollection;
    }

    public void setStringCollection(List<String> stringCollection) {
        this.stringCollection = stringCollection;
    }

    private HtmlDataTable dataTable;

    public HtmlDataTable getDataTable() {
        return dataTable;
    }

    public void setDataTable(HtmlDataTable dataTable) {
        this.dataTable = dataTable;
    }

    @PostConstruct
    public void init(){
        System.out.println("Post Construct fired!!");
        stringCollection = new ArrayList<String>();
        stringCollection.add("a");
        stringCollection.add("b");
        stringCollection.add("c");

    }

    public void action(){
        System.out.println("Clicked!!");

    }
}

ボタンをクリックするたびに@PostConstructが起動する理由を教えてください。私のBeanは@ViewScopedであるため、同じページにいる限り、1回だけ起動する必要があります。さらに、バインディング属性を削除すると、すべてが正常に機能し、@PostConstructコールバックが1回だけ発生します。では、なぜバインディング属性を使用するたびに?バインディング属性が必要で、Webサービスからのデータのフェッチなどの初期化タスクを1回だけ実行したい。私は何をすべきか?初期化タスクはどこに書くべきですか?

4

5 に答える 5

34

興味深いことに、ビュースコープのBeanでコンポーネントバインディングを使用している場合、ビュースコープが壊れます。

それがJSF2のバグかどうかはわかりませんが、最初にJSF2仕様全体を読む必要があります。これまでのところ、最善の策は、コンポーネントバインディングを今のところ削除し、選択したアイテムを新しいEL2.2メソッド引数構文を介して渡すことです。

<h:dataTable var="item" value="#{testBean.stringCollection}">
    <h:column>
        <h:outputText value="#{item}"/>
    </h:column>
    <h:column>
        <h:commandButton value="Click" action="#{testBean.action(item)}"/>
    </h:column>
</h:dataTable>

参照:


更新(2012年12月):これは確かにJSF2のバグです。卵の問題です。ビュースコープのBeanは、JSFビューステートで保存されます。したがって、ビュースコープのBeanは、ビューの復元フェーズの後でのみ使用できます。ただし、binding属性はビューの復元フェーズ中に実行されますが、ビュースコープのBeanはまだ使用できません。これにより、まったく新しいビュースコープのBeanインスタンスが作成され、その後、復元されたJSFビュー状態で保存された実際のビュースコープのBeanに置き換えられます。

これは、JSF問題1492およびJSF仕様問題787として報告されており、JSF2.2で修正される予定です。bindingそれまでは、要求に応じてスコープ付きBeanを排他的に使用するか、特定の機能要件の代替方法を探すのが最善の策です。


アップデート(2015年3月):JSF2.2の修正がMojarra2.1.18にバックポートされました。したがって、まだJSF 2.0 / 2.1を使用している場合は、少なくともそのバージョンにアップグレードすることをお勧めします。aoも参照してください。JSFのコンポーネントバインディングとは何ですか?いつ使用するのが好ましいですか?JSF2フェイスレットのJSTL...意味がありますか?

于 2010-05-09T16:37:42.010 に答える
4

他の人が言ったように、私がする最善のことは、コンポーネントのバインディングを削除することです(ここでは必要ありません)。

ただし、次のようなアクションパラメータを使用することで、よりオブジェクト指向の方法で実行しようとしているのと同じことを実現できることを付け加えておきます。

<h:commandButton value="Click" action="#{testBean.action(item)}"/>

...そしてあなたのJavaコードで:

  public void action(Item item){
    System.out.println("Clicked!!" + item);
}
于 2011-03-16T15:10:16.787 に答える
0

ビュースコープのBeanがあり、フォームに入力された値を保持したい場合、またはポストコンストラクトを起動したくない場合は、アクションメソッドからnullを返す必要があります。

何らかの結果(無効など)を返し、faces-config.xmlを使用して無効な結果を同じページにポイントすると、viewscoped Beanが再作成されるため、postconstructが再度起動します。

于 2013-03-26T17:20:53.753 に答える
0

その他の解決策:

  • リクエストスコープBeanでHtmlDataTableをバインドします。
  • この要求スコープBeanをビュースコープBeanに挿入します。

JBoss Seamは、JSFコンポーネントを会話スコープコンポーネントにバインドするためにこのソリューションを使用します。

于 2013-05-16T15:50:49.710 に答える
0

baluscの答えは私を大いに助けました、私はmojarraバージョン2.1.7でそのバグを持っていたと言いたいです、私は現在2015年1月にリリースされた2.1.29-01を使用しています、そしてこのバグは修正されました、私の問題はバインドされていましたビュースコープのBeanへのタブビュー。このバージョンでは、バグはなく、バインディングとpostconstructは正常に機能しています。私はJboss5.2を使用しており、mojarra 2.1.xを使用する必要があるため、この回答が同じ状況の他の人々に役立つことを願っています。

http://mvnrepository.com/artifact/com.sun.faces/jsf-api/2.1.29-01 http://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.1.29-01

于 2015-03-20T12:54:40.537 に答える