2013-01-09 13 views
7

ビュースコープ付きBeanに保存されたデータを別のビュースコープ付きBeanに使用する必要があります。別のビューのスコープ付きBeanに別のビュースコープ付きBeanを注入すると、再作成されます。

@ManagedBean 
@ViewScoped 
public class Attivita implements Serializable { 
    // 
} 

@ManagedBean 
@ViewScoped 
public class Nota implements Serializable { 

    @ManagedProperty("#{attivita}") 
    private Attivita attivita; 

    // Getter and setter. 
} 

さて、多分それについての私の理論はまだかなり貧弱である

、私は #{attivita}が注入されたときに、 Attivitaコンストラクタが呼び出されたことに気づいたので、別のインスタンスを作成します。それは正しい行動ですか?同じインスタンスを参照し、新しいインスタンスを作成しない場合はどうなりますか?

+0

正しい返答に注意してください。スタックオーバーフローは、それだけでなく、答えについての質問でもあります。 –

答えて

13

を管理。ビュースコープBeanは要求に結びついておらず、ビューに結びついています。したがって、新しいビューに移動すると、ビュースコープ付きBeanの新しいインスタンスが作成されます。以前のビューに関連付けられた同じBeanインスタンスを再利用しません。

最初のビューでattivitaのBeanが作成され、ポストバックで再利用されることを理解します。私はnota beanがあなたがナビゲートしている新しいビューに関連付けられていることを理解しています。 attivitaを注入すると、まったく同じリクエストに別のインスタンスがあるにもかかわらず、新しいインスタンスが作成されます。これはすべて予想される(そして、まったく直感的ではない)振る舞いです。

これには標準のJSFソリューションはありません。 CDIはこれを@ConversationScopedで解決します(Beanは明示的に生きている限りBeanが存続します)。また、CDI拡張MyFaces CODIは@ViewAccessScopedでさらに進んでいます(ナビゲーションビューが参照する限り、Beanは存続します)。

しかし、これを回避するには、リクエストスコープに属性としてBeanを格納します。

@ManagedBean 
@ViewScoped 
public class Attivita implements Serializable { 

    public String submit() { 
     FacesContext.getCurrentInstance().getExternalContext() 
      .getRequestMap().put("attivita", this); 
     return "nota"; 
    } 

} 

@ManagedBean 
@ViewScoped 
public class Nota implements Serializable { 

    private Attivita attivita; 

    @PostConstruct 
    public void init() { 
     attivita = (Attivita) FacesContext.getCurrentInstance().getExternalContext() 
      .getRequestMap().get("attivita"); 
    } 

} 

これはかなりハックされることに注意してください。具体的な機能要件によっては、より良い解決策があるかもしれません。 notaビューで希望のAttivita beanインスタンス(#{nota.attivita}および)を#{attivita}とする必要があります。なぜなら、これまでに説明した理由から、新しいインスタンスを提供するからです。

+0

これは確かに働きます - 私は同じ問題を抱えていました。しかし、あなたが述べたように非常にハッキリですが、JSFのもう一つの大きな欠点です。 PostConstructを追加する必要があり、Faces Contextから手動でBeanをプルする必要があるときは、CDIまたはManaged Propertiesの目的を排除します。 @ViewAccessScopedを標準のJSF APIに追加し、Myfacesの一部としてのみ追加する計画はありますか? – GreenieMeanie

+0

@GreenieMeanie:JSF 2.2ではこれをカバーするために '@ FlowScoped'を追加しましたが、残念ながらGETリクエストを生き残る必要があるため、XML設定と自動生成されたリクエストパラメータが必要です。たとえば、@ ViewAccessScopedと@ SessionScopedの間にあります。 「より良い解決策」として、エンティティIDをパラメータとしてリダイレクトするか、まったく同じビューの一部を別のインクルードと条件付きでレンダリングすることが考えられます。 a.oを参照してください。 http://stackoverflow.com/questions/15521451/how-to-navigate-in-jsf-how-to-make-url-reflect-current-page-and-not-previous-o – BalusC

+0

あなたはビューを持っていることをお勧めしますか? a.xhtmlはb.xhtmlへの "ダミー"インクルードを持ち、b.xhtmlのすべてのコンテンツを1つの巨大なui:wrapにラップすることができます(b.xhtml経由でリダイレクトされたときにのみレンダリングされます) a.xhtmlからのダミー参照として含まれていますか? – GreenieMeanie

1

attivita beanが@ViewScopedであり、インスタンスがセッション中に保持されることを保証するものではありません。あなたは@SessionScoped beanが必要です。ただし、何らかの理由でattivita@ViewScopedになる必要がある場合は、他の方法でパラメータを渡すことができます。 viewParamを使用するか、またはそれらの間に別のBeanを使用します。

ページのparams

http://mkblog.exadel.com/2010/07/learning-jsf2-page-params-and-page-actions/

JSF 2を使用すると、1からポストバック上の他のビューにナビゲートしている場合、これが起こる豆スコープ

http://balusc.blogspot.com.es/2011/09/communication-in-jsf-20.html#ManagedBeanScopes

関連する問題