2010-11-27 17 views
3

私はこの問題を解決する最良の方法は、ちょうど私のコードを貼り付けることであると思う:JSF - Ajaxコール - このコードで何が間違っていますか?

Selector bean

@ManagedBean(name="selector") 
@RequestScoped 
public class Selector { 
    @ManagedProperty(value="#{param.page}") 
    private String page; 
    private String profilePage; 

    @PostConstruct 
    public void init() { 
     if(profilePage==null || profilePage.trim().isEmpty()) { 
      this.profilePage="main"; 
     } 

     if(page==null || page.trim().isEmpty()) { 
      this.page="homepage"; 
     } 
    } 

    public String getProfilePage() { System.out.println("GET ="+profilePage); return profilePage; } 
    public void setProfilePage(String profilePage) { this.profilePage=profilePage; } 

    public String getPage() { return page; } 
    public void setPage(String page) { this.page=page; } 
}  

profile.xhtml

<h:panelGroup layout="block" id="profileContent"> 
    <h:panelGroup rendered="#{selector.profilePage=='main'}"> 
     <ui:include src="/profile/profile_main.xhtml" /> 
    </h:panelGroup> 

    <h:panelGroup rendered="#{selector.profilePage=='edit'}"> 
     <ui:include src="/profile/profile_edit.xhtml" /> 
    </h:panelGroup> 
</h:panelGroup> 

profile_main.xhtml

<h:form id="formProfileMain" prependId="false"> 
    <h:panelGroup layout="block"> 
     <h:outputScript name="jsf.js" library="javax.faces" target="head" /> 

     <h:outputLabel value="MAIN" /> 

     <h:panelGroup layout="block" > 
      <h:commandButton value="Edit Button"> 
       <f:setPropertyActionListener target="#{selector.profilePage}" value="edit" /> 
       <f:ajax event="action" render=":profileContent"/> 
      </h:commandButton> 
     </h:panelGroup> 
    </h:panelGroup> 
</h:form>  

profile_edit.xhtml

<h:panelGroup layout="block" id="profileEditContent"> 
    <h:panelGroup rendered="#{selector.profilePage=='edit'}"> 
     <h:form id="formProfileEdit" prependId="false"> 
      <h:panelGroup layout="block"> 
       <h:outputScript name="jsf.js" library="javax.faces" target="head" /> 

       <h:outputLabel value="EDIT" /> 

       <h:panelGroup layout="block"> 
        <h:commandButton value="Confirm Edit"> 
         <f:setPropertyActionListener target="#{selector.profilePage}" value="editConfirm" /> 
         <f:ajax event="action" render=":profileEditContent"/> 
        </h:commandButton> 

        <h:commandButton value="Back"> 
         <f:setPropertyActionListener target="#{selector.profilePage}" value="main" /> 
         <f:ajax event="action" render=":profileEdit"/> 
        </h:commandButton> 
       </h:panelGroup> 
      </h:panelGroup> 
     </h:form> 
    </h:panelGroup> 

    <h:panelGroup rendered="#{selector.profilePage=='editConfirm'}"> 
     <h:outputLabel value="FINALLY IM HERE" /> 
    </h:panelGroup> 
</h:panelGroup>   

私は編集ボタンに最初にクリックして、の確認、編集上よりも、私は(結果として)を取得しようとするとラベルとページFINALLY IM HERE 残念ながら、このdoesntのことが起こります。 編集ボタンをクリックした後、をクリックしてください。を編集しても何も起こりません。

私は間違っていますか?乾杯

新しいバージョンでUPDATE

bean

@ManagedBean 
@ViewScoped 
public class ProfileSelector { 
    private String profilePage; 

    @PostConstruct 
    public void init() { 
     if(profilePage==null || profilePage.trim().isEmpty()) { 
      this.profilePage="main"; 
     } 
    } 

    public String getProfilePage() { return profilePage; } 
    public void setProfilePage(String profilePage) { this.profilePage=profilePage; } 
} 

profile.xhtml

<h:panelGroup layout="block" id="profileContent"> 
    <h:form id="formProfile" prependId="false"> 
     <h:outputScript name="jsf.js" library="javax.faces" target="head" /> 

     <h:panelGroup rendered="#{profileSelector.profilePage=='main'}"> 
      <ui:include src="/profile/profile_main.xhtml" /> 
     </h:panelGroup> 

     <h:panelGroup rendered="#{profileSelector.profilePage=='edit'}"> 
      <ui:include src="/profile/profile_edit.xhtml" /> 
     </h:panelGroup> 
    </h:form> 
</h:panelGroup> 

profile_main.xhtml

<h:panelGroup layout="block">    
    <h:outputLabel value="MAIN" /> 

    <h:panelGroup layout="block"> 
     <h:commandButton value="Edit Button"> 
      <f:setPropertyActionListener target="#{profileSelector.profilePage}" value="edit" /> 
      <f:ajax event="action" render=":profileContent"/> 
     </h:commandButton> 
    </h:panelGroup> 
</h:panelGroup> 
複雑になるまあ

profile_edit.xhtml

<h:panelGroup layout="block" id="profileContentEdit"> 
    <h:panelGroup rendered="#{profileSelector.profilePage=='edit'}"> 
     <h:panelGroup layout="block">     
      <h:outputLabel value="EDIT" /> 

      <h:panelGroup layout="block" styleClass="profilo_3"> 
       <h:commandButton value="Confirm Edit"> 
        <f:setPropertyActionListener target="#{profileSelector.profilePage}" value="editConfirm" /> 
        <f:ajax event="action" render=":profileContentEdit"/> 
       </h:commandButton> 

       <h:commandButton value="Back"> 
        <f:setPropertyActionListener target="#{profileSelector.profilePage}" value="main" /> 
        <f:ajax event="action" render=":profileContent"/> 
       </h:commandButton> 
      </h:panelGroup> 
     </h:panelGroup> 
    </h:panelGroup> 

    <h:panelGroup rendered="#{profileSelector.profilePage=='editConfirm'}"> 
     <h:outputLabel value="FINALLY Im HERE" /> 
    </h:panelGroup> 
</h:panelGroup> 

答えて

5

、。 UICommandアクションが呼び出されるかどうかは、コンポーネントまたはその親の1つの属性の結果によって異なります。 Beanが要求スコープ内にあるため、profilePageは次の要求でデフォルトでmainに戻ります。したがって、編集セクションのrendered属性はfalseと評価されるため、編集セクションのボタンは何も実行されません。これはあなたのprevious questionで回答されています。

理論上、Beanにマークを付けると、後でビューにBeanの状態が保持されるため、これを修正する必要があります。しかし、あなたの特定のケースでは、正常に動作しないようにする2つの問題があります。

まず、@ManagedPropertyを使用しています。これは、より短い範囲にある値を参照しています(#{param}は基本的にスコープが要求されています)。 profilePageを別のBeanに分割し、これを@ViewScopedとマークする必要があります。あなたはすべて同じBeanに添付されている別のrendered状態で複数の<h:form>を持っているのでJSF2で現在まだ開いバグ(issue 1718)による

第二には、あなたの特定のケースではまだ動作しません。この特定の状況では、返された応答には完全に欠損しているjavax.faces.ViewStateが発生します。これにより、ビュースコープのBeanがガベージされ、再作成されます(profilePageのデフォルト値はmainになります)。一時的な回避策として、最初の<h:panelGroup>の直接の子としてprofile.xhtmlに1つのフォームにフォームを抽出してマージする必要があります。


更新:あなたの唯一の懸念は、あなたがお互いに豆を接続したいということであれば、以下のように、あなたは豆を分割することができます:

@ManagedBean 
@RequestScoped 
public class Selector { 
    @ManagedProperty(value="#{param.page}") 
    private String page; 

    @ManagedProperty(value="#{profileSelector}") 
    private ProfileSelector profileSelector; 

    // ... 
} 

@ManagedBean 
@ViewScoped 
public class ProfileSelector { 
    private String profilePage; 

    // ... 
} 

ビュースコープ付きBeanは、このようにリクエストスコープ付きBeanでアクセスできます。

それとも、あなた本当には、単一のBeanを持つようにしたい場合は、次のように回避策としても@ManagedPropertyを置き換えることができます。

@ManagedBean 
@ViewScoped 
public class Selector { 
    private String page; 
    private String profilePage; 

    @PostConstruct 
    public void init() { 
     page = FacesContext.getCurrentInstance().getRequestParameterMap().get("page"); 
    } 

    // ... 
} 
+0

おおを。少なくとも今、私は、それが行列の始まりに「メイン」を持つコンポーネントツリーを作成する理由を理解しています。 RequestStopeでセレクタBeanが必要なので、私は戦略を変更する必要があると思います:)残念ながら、jsfを使ってajax呼び出しで自分のディナミズムメニューを実装する方法は他にありません。 – markzzz

+0

本当に '@ ViewScoped'が必要です。これにアプローチする方法については、回答の更新を参照してください。 – BalusC

+0

ええ、私は2つの別の豆(最高の可視性)に分割。試してみましたが、現時点でレンダリングをロードしています。もう少しお試しください! – markzzz

関連する問題