2

コードがバッキング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);

FacesConfigでハンドラーとして定義されているRequestHandlerBeanというバッキングBeanには、次のコードがあります。

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

ボタンをクリックしても何も起こらない理由を誰かが見つけますか?イベントが適切にトリガーされていません。htmlコードのソースは次のとおりです。

<input id="replyCommentButton1" type="submit" value="Create reply"   
name="replyCommentButton1"/>

ご覧のとおり、HTMLで定義されたアクションはありません。

編集2: Javadocで、アクションメソッドはパブリック文字列でなければならないことがわかりました。バッキングBeanでこれを変更したので、バッキングBeanのコードは次のようになります。

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

Edit2:タグ内にカプセル化されていることも確認しましたが、それでも運がありません。要素にアクション属性があるべきではありませんか?


Edit3:私のBeanは次のように私のfaces-configで定義されています:

<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>

また、JSFページに次のように出力することを選択した場合:

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

それは完璧に機能します

編集4-私のJSPページ 注減価償却された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;
    }
}
4

2 に答える 2

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 を作成するために、コードを見直す必要があるかもしれません。レンダリングフェーズ...

于 2009-03-24T10:16:04.923 に答える
1

コードは正しいようです(実際、メソッドは文字列を返す必要がありますが、そのようなアクションメソッドを作成するように推奨されていない場合でも、voidを返すこともあります)。

作成されたcommandButtonがコンポーネント内にネストされていることを確認しますか?そうしないと、機能しません。つまり、(JavaまたはJSFページで作成された)には、(JSFコンポーネントツリー内の)直接または間接の親コンポーネントが必要です。例えば:

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

問題をクリックしたときにJavascriptエラーが発生しましたか?

コメントに関して編集します。

メイン投稿への私のコメントに関して、2を編集します。

たぶん、古い方法でボタンにアクションをアタッチすることを試みることができます(わかりました、それは非推奨ですが、試してみてください):

replyCommandButton.setAction(context.getApplication().createMethodBinding("#{Handler.action_replyToComment}", null));
于 2009-03-20T11:13:45.537 に答える