2009-03-20 19 views
2

私のコードが私のバッキングBeanでアクションを引き起こしていないという問題があります。次のようにコードがある:私はボタンをクリックしても何も起こらない理由JSF MethodExpressionがバッキングBeanのアクションを起動していません

public void action_replyToComment() { 
logger.info("Homemade action called!!!"); 
System.out.println("Homemade action called!!!"); 
} 

誰でも見つけるん:ハンドラとしてFacesConfigで定義されてRequestHandlerBeanと呼ばれる私のバッキングBeanでは、

HtmlCommandButton replyCommentButton = new HtmlCommandButton(); 
replyCommentButton.setId("replyCommentButton" + commentCounter); 
replyCommentButton.setValue("Create reply"); 
String action = "#{Handler.action_replyToComment}"; 
MethodExpression methodExpression = 
FacesContext.getCurrentInstance().getApplication().getExpressionFactory(). 
createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, null, 
new Class<?>[0]); 
replyCommentButton.setActionExpression(methodExpression); 

を、私は次のコードを持っています?イベントを適切にトリガーしていません。 HTMLコードのソースは次のとおりです。

HTMLで定義されているアクションはありません。

編集2:私はJavadocで、自分のアクションメソッドがパブリックStringでなければならないことを知りました。

public String action_replyToComment() { 
logger.info("Homemade action called!!!"); 
System.out.println("Homemade action called!!!"); 
return null; 
} 

EDIT2:私のバッキングBeanのコードがあるので、私は今、私のバッキングBeanでこれを変更した私も、私はそれがタグ内にカプセル化していることを確認しましましたが、まだ運。要素にアクション属性があってはなりませんか?


EDIT3:

<a4j:commandButton action="#{Handler.action_replyToComment}" value="Reply" /> 

:私はこのような私のJSFページに出力することを選択した場合も

<managed-bean> 
<description> 
Handles the specific request. 
</description> 
<managed-bean-name>Handler</managed-bean-name> 
<managed-bean-class>no.ngt.tech.rt2.beans.RequestHandlerBean</managed-bean-class> 
<managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 

:私のBeanは、このように私の顔-config設定で定義されていますそれは完全に動作します

EDIT 4 - MY JSP PAGE メモまた、償却されたsetAction(methodBinding)も使用しようとしましたが、残念ながら、どちらも機能しませんでした。

<%@ include file="_includes.jsp" %> 
<f:view> 
<html> 
<head> 
<title><h:outputText value="#{msgs.title}" /></title> 
</head> 
<body> 
<br /><br /><br /> 



<%@ include file="_menu.jsp" %> 

<rich:tabPanel switchType="client"> 

<rich:tab id="commentsTab" label="Comments" rendered="#{Handler.editRequest}"> 
<h:form> 
     <ngt:commentTree binding="#{Handler.commentTree}" value="#{Handler.comments}" /> 

     <br /> 

     <a4j:commandButton action="#{Handler.action_replyToComment}" value="testbutton" /> 
</h:form>  
</rich:tab> 


</rich:tabPanel> 

</body> 
</html> 
</f:view> 

menu.jsp:

<h:form> 
    <rich:toolBar itemSeparator="line" styleClass="toolbar" contentClass="toolbar" height="22"> 
     <rich:toolBarGroup> 
      <rich:menuItem submitMode="server" value="Front" action="#{newRT.action_showFront}" /> 
     </rich:toolBarGroup> 
     <rich:toolBarGroup> 
      <rich:menuItem submitMode="server" value="New request" action="#{Step.action_showSteps}" /> 
     </rich:toolBarGroup> 
     <rich:toolBarGroup> 
      <rich:menuItem submitMode="server" value="Requests" action="#{Handler.action_showRequestsView}" /> 
     </rich:toolBarGroup> 
     <rich:toolBarGroup> 
      <rich:menuItem submitMode="server" value="Control-panel" action="#" /> 
     </rich:toolBarGroup> 
     <rich:toolBarGroup location="right"> 
      <h:inputText styleClass="barsearch" value="#{Handler.search}" /> 
      <a4j:commandButton styleClass="barsearchbutton" action="#{Handler.action_GetRequestFromID}" value="Search" /> 
     </rich:toolBarGroup> 
    </rich:toolBar> 
</h:form> 


<br/><br/> 

Includes.jsp

<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> 
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%@ taglib prefix="a4j" uri="http://richfaces.org/a4j" %> 
<%@ taglib prefix="rich" uri="http://richfaces.org/rich"%> 
<%@ taglib prefix="ngt" uri="http://MySpecialTagLib.no/"%> 

編集7 - UIComponentのJavaコード:

これはCommentsTreeUI.javaです:

public class CommentsTreeUI extends UIOutput { 

    private static Logger logger = Logger.getLogger(CommentsTreeUI.class.getName()); 

    @Override 
    public void encodeBegin(FacesContext context) throws IOException { 

     List<CommentTag> value = (List<CommentTag>) getAttributes().get("value"); 
     int commentCounter = 0; 

     if (value != null) { 
      for (CommentTag comment : value) { 
       commentCounter++; 
       ResponseWriter commentContainerWriter = context.getResponseWriter(); 
       commentContainerWriter.startElement("div", this); 
       commentContainerWriter.writeAttribute("id", "Comment" + commentCounter, null); 

       String width = comment.getWidth(); 
       String height = comment.getHeight(); 

       String style = comment.getStyle(); 

       style = (style != null) ? style + ";" : ""; 

       if (width != null) { 
        style += "width:" + width + ";"; 
       } 
       if (height != null) { 
        style += "height:" + height + ";"; 
       } 

       commentContainerWriter.writeAttribute("style", style, null); 

       String newComment = comment.getNewComment(); 
       if (newComment == null) { 
        newComment = "false"; 
       } 

       String level = comment.getLevel(); 

       if (level != null) { 
        level = "commentContainerLevel" + level + newComment; 
       } 
       commentContainerWriter.writeAttribute("class", level, null); 

       String title = comment.getTitle(); 
       if (title != null) { 
        commentContainerWriter.writeAttribute("title", title, null); 
       } 

       String titleText = comment.getTitleText(); 
       if (titleText != null) { 
        ResponseWriter titleTextWriter = context.getResponseWriter(); 
        UIOutput titleTextComponent = new UIOutput(); 
        titleTextWriter.startElement("div", titleTextComponent); 
        titleTextWriter.writeAttribute("class", "commentHeaderText" + newComment, null); 
        titleTextWriter.writeText(titleText + " | ", null); 
        titleTextWriter.startElement("a", titleTextComponent); 
        titleTextWriter.writeAttribute("onclick", "showCommentReply('CommentReply" + commentCounter + "')", null); 
        titleTextWriter.writeAttribute("class", "reply", null); 
        titleTextWriter.writeText("Reply", null); 
        titleTextWriter.endElement("a"); 
        titleTextWriter.endElement("div"); 
       } 

       String commentBody = comment.getCommentBody(); 
       if (commentBody != null) { 
        ResponseWriter commentBodyWriter = context.getResponseWriter(); 
        UIOutput commentBodyComponent = new UIOutput(); 
        commentBodyWriter.startElement("div", commentBodyComponent); 
        commentBodyWriter.writeText(commentBody, null); 
        commentBodyWriter.endElement("div"); 
       } 

       ResponseWriter replyContainerWriter = context.getResponseWriter(); 
       UIOutput replyContainerComponent = new UIOutput(); 
       replyContainerWriter.startElement("div", replyContainerComponent); 
       commentContainerWriter.writeAttribute("id", "CommentReply" + commentCounter, null); 
       replyContainerWriter.writeAttribute("class", "replyContainer", null); 

       ResponseWriter replyHeaderWriter = context.getResponseWriter(); 
       UIOutput replyHeaderComponent = new UIOutput(); 
       replyHeaderWriter.startElement("div", replyHeaderComponent); 
       replyHeaderWriter.writeAttribute("class", "replyHeaderContainer", null); 
       replyHeaderWriter.endElement("div"); 

       ResponseWriter replyFormWriter = context.getResponseWriter(); 
       UIInput replyFormComponent = new UIInput(); 
       replyFormWriter.startElement("fieldset", replyFormComponent); 
       replyFormWriter.startElement("textarea", replyFormComponent); 
       replyFormWriter.writeAttribute("type", "textarea", null); 
       replyFormWriter.writeAttribute("rows", "5", null); 
       replyFormWriter.writeAttribute("cols", "76", null); 
       replyFormWriter.writeText("Write your answer here", null); 
       replyFormWriter.endElement("textarea"); 


       //TODO: Fix so button has action to backing bean 
       HtmlAjaxCommandButton replyCommentButton = new HtmlAjaxCommandButton(); 
       replyCommentButton.setId("replyCommentButton" + commentCounter); 
       replyCommentButton.setValue("Create reply"); 
       String action = "#{RequestHandlerBean.action_replyToComment}"; 
       //replyCommentButton.setReRender("commentsTree"); 
       ExpressionFactory factory = context.getApplication().getExpressionFactory(); 
       Class [] argtypes=new Class[1]; 
       argtypes[0]=ActionEvent.class; 

       MethodExpression replyActionExpression = factory.createMethodExpression(context.getELContext(), action, null, argtypes); 
       replyCommentButton.setActionExpression(replyActionExpression); 

       MethodExpression methodExpression = context.getCurrentInstance().getApplication().getExpressionFactory(). 
         createMethodExpression(context.getCurrentInstance().getELContext(), action, null, new Class<?>[0]); 
       replyCommentButton.setActionExpression(methodExpression); 
       /* 
       replyCommentButton.setAction(context.getApplication().createMethodBinding(action, argtypes)); 
       */ 

       replyCommentButton.encodeAll(context); 
       //Todo above 


       replyFormWriter.writeText(" ", null); 
       replyFormWriter.startElement("input", replyFormComponent); 
       replyFormWriter.writeAttribute("type", "button", null); 
       replyFormWriter.writeAttribute("value", "Cancel ", null); 
       replyFormWriter.writeAttribute("onclick", "hideCommentReply('CommentReply" + commentCounter + "')", title); 
       replyFormWriter.endElement("input"); 
       replyFormWriter.endElement("fieldset"); 
       replyContainerWriter.endElement("div"); 
       commentContainerWriter.endElement("div"); 
      } 
     } else { //value==null 
      ResponseWriter writer = context.getResponseWriter(); 
      writer.startElement("div", this); 

      writer.writeAttribute("id", getClientId(context), null); 

      String width = (String) getAttributes().get("width"); 
      String height = (String) getAttributes().get("height"); 

      String style = (String) getAttributes().get("style"); 

      style = (style != null) ? style + ";" : ""; 

      if (width != null) { 
       style += "width:" + width + ";"; 
      } 
      if (height != null) { 
       style += "height:" + height + ";"; 
      } 

      writer.writeAttribute("style", style, null); 

      String styleClass = (String) getAttributes().get("styleClass"); 
      if (styleClass != null) { 
       writer.writeAttribute("class", styleClass, null); 
      } 

      String title = (String) getAttributes().get("title"); 
      if (title != null) { 
       writer.writeAttribute("title", title, null); 
      } 

     } 
    } 

    @Override 
    public void encodeEnd(FacesContext context) throws IOException { 
     ResponseWriter writer = context.getResponseWriter(); 
     writer.endElement("div"); 
    } 

これはCommenstTreeTagです:

public class CommentsTreeTag extends UIComponentTag { 

    String style; 
    String styleClass; 
    String title; 
    String width; 
    String height; 
    String value; 
    Long parentId; 

    public void release() { 
     // the super class method should be called 
     super.release(); 
     style = null; 
     styleClass = null; 
     title = null; 
     height = null; 
     width = null; 
     parentId = null; 
     value = null; 
    } 

    @Override 
    protected void setProperties(UIComponent component) { 
     // the super class method should be called 
     super.setProperties(component); 

     if (style != null) { 
      component.getAttributes().put("style", style); 
     } 

     if (styleClass != null) { 
      component.getAttributes().put("styleClass", styleClass); 
     } 

     if (width != null) { 
      component.getAttributes().put("width", width); 
     } 

     if (height != null) { 
      component.getAttributes().put("height", height); 
     } 

     if (title != null) { 
      if (isValueReference(title)) { 
       ValueBinding vb = 
         getFacesContext().getApplication().createValueBinding(title); 
       component.setValueBinding("title", vb); 
      } else { 
       component.getAttributes().put("title", title); 
      } 
     } 
     if (value != null) { 
      if (isValueReference(value)) { 
       ValueBinding vb = 
         getFacesContext().getApplication().createValueBinding(value); 
       component.setValueBinding("value", vb); 
       getFacesContext().getApplication().createValueBinding(value); 

      } else { 
       component.getAttributes().put("value", value); 
      } 
     } 
     if (parentId != null) { 
      component.getAttributes().put("parentId", parentId); 
     } 
    } 



    public String getComponentType() { 
     return "commentTree"; 
    } 

    public String getRendererType() { 
     // null means the component renders itself 
     return null; 
    } 

    public String getHeight() { 
     return height; 
    } 

    public void setHeight(String height) { 
     this.height = height; 
    } 

    public String getWidth() { 
     return width; 
    } 

    public void setWidth(String width) { 
     this.width = width; 
    } 

    public String getStyle() { 
     return style; 
    } 

    public void setStyle(String style) { 
     this.style = style; 
    } 

    public String getStyleClass() { 
     return styleClass; 
    } 

    public void setStyleClass(String styleClass) { 
     this.styleClass = styleClass; 
    } 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public String getValue() { 
     return value; 
    } 

    public void setValue(String value) { 
     this.value = value; 
    } 
} 
+0

html出力ではなく、jsfページの関連コードを知りたいと思います。あなたはそれを追加できますか? – alexmeia

+0

おそらく、(createMethodExpressionの代わりにcreateMethodBindingを使って)最も古い方法で試すことができます。私の編集応答を参照してください。 – romaintaz

+0

完全なJavaコードを表示できますか? Javaで作成したコンポーネントをJSFコンポーネントツリーにどのように追加しますか? – romaintaz

答えて

3

あなたが遭遇する問題は、JSFコンポーネントツリーにcommandButtonを追加する方法、または正確にはコンポーネントツリーに追加しない方法によるものだと思います。

commandButtonをJSFコンポーネントツリーにアタッチしないので、このコンポーネントが(.encodeAll()メソッドの呼び出しによって)レンダリングされるとき、このコンポーネントがネストされているフォームは見つかりません。 したがって、HTML入力は正しく作成されません。

フォームに作成されたcommandButtonをレンダリングする前に直接追加することができます。

それはまだ動作しない場合は...ので、多分あなたはそれを少し変更する必要があり、

// Search for the component HtmlForm that is a (in)direct parent of the current component 
private UIComponent getCurrentForm(UIComponent currentComponent) { 
    UIComponent parent = currentComponent.getParent(); 
    while ((parent != null) && !(parent instanceof HtmlForm)) { 
     parent = parent.getParent(); 
    } 
    return parent; 
} 


public void encodeBegin(FacesContext context) throws IOException { 
    ... 
    HtmlAjaxCommandButton replyCommentButton = new HtmlAjaxCommandButton(); 
    ... 

    // Add the command button in the form that contains your custom component... 
    UIComponent form = getCurrentForm(this); 
    if (form != null) { 
     form.getChildren().add(replyCommentButton); 
    } 
    replyCommentButton.encodeAll(context); 
    ... 
} 

ノート私はこのコードをテストしてみた:あなたは、次のコードでそれを行うことができますレンダリングクラスの外かencodeBeginの外にcommandButtonを作成するためにコードを見直す必要があるかもしれません...レンダリングフェーズでJSFコンポーネントツリーを変更するのは良い考えではありません。

+0

これは完璧に機能しました!どうもありがとうございました! –

+0

これを行うともう一つの問題が発生しました。問題は、子としてボタンを追加すると、2回エンコードされるという問題です。フォームがエンコードされるときは1回、commentButtonReply.encodeAll(コンテキスト)を実行するときは1回です。何か案は? –

+0

おそらく、フォームに含まれているHtmlFormコンポーネントではなく、現在のコンポーネントにcommandButtonを追加しようとすると、encodeAllを自分で呼び出すことはできません。 – romaintaz

1

あなたのコードは実際には、この方法は、文字列を返す必要があります(正しいように思えるが、それはまたしても、voidを返すことができますそのようなアクションメソッドを書くことはお勧めしません)。

作成されたcommandButtonがコンポーネント内にネストされていますか?それ以外の場合、動作しません。 これは、(JavaまたはJSFページで作成されていても)直接的または間接的な親(JSFコンポーネントツリー内)にコンポーネントが必要であることを意味します。例:

<h:form> 
    ... 
    <h:commandButton .../> 
    ... 
</h:form> 

問題をクリックすると、Javascriptエラーが発生しましたか?

コメントに関する編集。

はたぶん、あなたは古い方法で、ボタンにアクションを添付しようとすることができます(OK、それは推奨されませんが、ちょうどそれを試してみる):メインの記事に私のコメントについて

編集2、

replyCommandButton.setAction(context.getApplication().createMethodBinding("#{Handler.action_replyToComment}", null)); 
+0

Firefoxのエラーコンソールをチェックすると、Javascriptのエラーが表示されません。 「コンポーネント内のネスト」とはどういう意味ですか?私のコードは、CommentsTreeUIで宣言されているtaglibrary内で、そしてencodeBeginのメソッド内で起こっています。私はのタグを付けて試してみました。 –

+0

私はちょっと正確に私の投稿を編集しました。 – romaintaz

+0

はい、私はあなたが思っていたものです。 JSFページのh:form要素にカプセル化しようとしました。まだ動作していないし、ソースコードにアクション属性が追加されていないことがわかりました。 –

関連する問題