0

不明な理由で、AJAX リクエストが JSF で起動しないという問題があります。

admin.xhtml スニペット:

<h:form id="adminPanel">
...
<f:subview id="editCustomer#{customer.id}">
    <p class="#{adminService.getEditCustomerClass(customer.id)}">
        <h:inputText id="email#{customer.id}" value="#{adminService.customerEmail}"/><br/>
        <h:inputText id="firstName#{customer.id}" value="#{adminService.customerFirstName}"/>
        <h:inputText id="lastName#{customer.id}" value="#{adminService.customerLastName}"/><br/>
        <h:commandButton id="saveEdit#{customer.id}" type="button" value="Save">
            <f:ajax render="@form" event="click" listener="#{adminService.saveCustomer()}"/>
        </h:commandButton>
        <h:commandButton id="cancelEdit#{customer.id}" type="button" value="Cancel">
            <f:ajax render="@form" event="click" listener="#{adminService.cancelEdit()}"/>
        </h:commandButton>
    </p>
</f:subview>
...
</h:form>

AdminService.java スニペット:

@Named
@Stateless
@LocalBean
public class AdminService {

    public String getEditCustomerClass(int id) {
        return id != customerId ? "hidden" : "";
    }

    public void saveCustomer() {
        cancelEdit();
    }

    public void cancelEdit() {
        movieId = -1;
        customerId = -1;
        orderId = -1;
        actorId = -1;
        employeeId = -1; //if none of the id's match, p should return 'hidden' class and not be seen.
    }

}

CSS で表示と非表示を切り替える代わりに、"rendered=" 属性を使用していたため、最初は問題がありました。ただし、ビューの部分的なレンダリングは AJAX を壊す可能性があると聞いたので、ビューを部分的にレンダリングしない (非表示にして表示するだけ) ことで問題が解決することを期待して、段階的に廃止しました。

ただし、この ajax は、listener 属性で指定したメソッドをまだ呼び出していません (ページ全体がはるかに大きく、より多くの AJAX を使用していますが、残りの部分はこれらのボタンが押されるまで機能し、その後他の ajax ボタンが応答しなくなります)。

ボタンのタイプを送信に変更すると、ボタンを 2 回押すと実際にリスナー メソッドが実行されますが、他の ajax リンクはそれぞれのリスナー メソッドを呼び出しません。

どうすればこれを機能させることができますか?

アップデート:

以下は、クリック時に JSF が起動する POST リクエストからの情報です。

リクエスト ヘッダー:

Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:2186
Content-type:application/x-www-form-urlencoded;charset=UTF-8
Cookie:JSESSIONID=7342e0de92edc023eecbf706dae3
Faces-Request:partial/ajax
Host:www.minimalcomputers.com:8181
Origin:https://www.minimalcomputers.com:8181
Referer:https://www.minimalcomputers.com:8181/MovieProject/Admin/admin.xhtml
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31

フォームデータ:

adminPanel:adminPanel
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:lastName1:
javax.faces.ViewState:1088200739038195170:4402027985833798256
javax.faces.source:adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1
javax.faces.partial.event:click
javax.faces.partial.execute:adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1             adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1
javax.faces.partial.render:adminPanel
javax.faces.behavior.event:click
javax.faces.partial.ajax:true

応答ヘッダー

Cache-Control:no-cache
Content-Type:text/xml;charset=UTF-8
Date:Thu, 02 May 2013 21:45:05 GMT
Server:GlassFish Server Open Source Edition 3.1.2.2
Transfer-Encoding:chunked
X-Powered-By:Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.2.2 Java/Sun Microsystems Inc./1.6)
X-Powered-By:JSF/2.0

更新 2:

AJAX を使用せずに「submit」タイプの commandButtons に切り替えると、期待どおりに動作します (ただし、一部のボタンをアクティブにするには 2 回クリックする必要があります)。したがって、問題は f:ajax タグに限定されます。

更新 3:

admin.xhtml のコードのベース全体。IT は、デバッグ中であり、動作させるための試みを行っている最中であるため、少し汚れています。

<?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:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"/>
        <h:outputStylesheet name="header.css" library="css"/>
        <link href='http://fonts.googleapis.com/css?family=Noto+Sans' rel='stylesheet' type='text/css'/>
        <title>VideoPile - Administration</title>
    </h:head>
    <h:body>
        <div id="body">
            <ui:insert name="header" >
                <ui:include src="/templates/header.xhtml" />
            </ui:insert>
            <div id="content">
                Admin.
                <h:form id="adminPanel">
                    <!--<h:commandButton id="admin" value="Administrative Actions" rendered="{adminService.hasAdminPrivileges()}">
                        <f:ajax render="@form" event="click" listener="{adminService.toggleAdminPane()}"/>
                    </h:commandButton>-->
                    <h:commandButton id="manager" type="button" value="Manager Actions" rendered="#{adminService.hasManagerPrivileges()}">
                        <f:ajax render="@form" event="click" listener="#{adminService.toggleManagerPane()}"/>
                    </h:commandButton>
                    <h:commandButton id="representative" type="button" value="Representative Actions" rendered="#{adminService.hasRepresentativePrivileges()}">
                        <f:ajax render="@form" event="click" listener="#{adminService.toggleRepresentativePane()}" />
                    </h:commandButton>
                    <br/>
                    <!--<f:subview id="administrativeActionPane" rendered="{userService.showAdminPane}">
                        Admin Pane
                    </f:subview>-->
                    <f:subview id="managerialActionPane">
                        <div class="#{adminService.getShowManagerClass()}">
                        Manager Pane:
                        <h:commandLink id="editmovies" value="Movies">
                            <f:ajax render="@form" event="click" listener="#{adminService.toggleMoviePane()}"/>
                        </h:commandLink>
                        <h:commandLink id="employes" value="Employees">
                            <f:ajax render="@form" event="click" listener="#{adminService.toggleEmployeePane()}"/>
                        </h:commandLink>
                        <h:commandLink id="sales" target="_blank" value="View Sales Report" action="/Admin/salesreport"/>
                        <h:commandLink id="employees" target="_blank" value="View Most Active Employees" action="/Admin/activeemployees"/>
                        <h:commandLink id="customers" target="_blank" value="View Most Active Customers" action="/Admin/activecustomers"/>
                        <h:commandLink id="movies" target="_blank" value="View Most Active Movies" action="/Admin/activemovies"/>
                        <br/>
                        <f:subview id="moviesEditPane">
                            <span class="#{adminService.getShowMovieClass()}">
                                Movies.
                                <ui:repeat value="#{adminService.currentMoviePage}" var="movie">
                                    #{movie.name}
                                    <h:commandLink id="edit" value="Edit">
                                        <f:ajax render="@form" event="click" listener="#{adminService.editMovie(movie.id)}"/>
                                    </h:commandLink> 
                                    <h:outputText rendered="#{adminService.movieId eq movie.id}" value="edit"/>
                                    <br/>
                                </ui:repeat>
                            </span>
                        </f:subview>
                        <f:subview id="employeesEditPane">
                            <span class="#{adminService.getShowEmployeeClass()}">
                                Employees.
                                <ui:repeat value="#{adminService.currentEmployeePage}" var="employee">
                                    #{employee.firstName} #{employee.lastName}
                                    <h:commandLink id="edit" value="Edit">
                                        <f:ajax render="@form" event="click" listener="#{adminService.editEmployee(employee.id)}"/>
                                    </h:commandLink> 
                                    <h:outputText rendered="#{adminService.employeeId eq employee.id}" value="edit"/>
                                    <br/>
                                </ui:repeat>
                            </span>
                        </f:subview>
                        </div>
                    </f:subview>
                    <f:subview id="representativeActionPane">
                        <div class="#{adminService.getShowRepresentativeClass()}">
                            Customer Representative Pane:
                            <h:commandLink id="recordOrder" value="Record Order">
                                <f:ajax render="@form" event="click" listener="#{adminService.toggleOrderPane()}"/>
                            </h:commandLink>
                            <h:commandLink id="customers" value="Customers">
                                <f:ajax render="@form" event="click" listener="#{adminService.toggleCustomerPane()}"/>
                            </h:commandLink>
                            <h:commandLink id="mailingList" target="_blank" value="View Mailing List" action="/Admin/mailinglist"/>
                            <f:subview id="orderPane">
                                <span class="#{adminService.getShowOrderClass()}">
                                    Create new order.
                                </span>
                            </f:subview>
                            <f:subview id="customerPane">
                                <span class="#{adminService.getShowCustomerClass()}">
                                    Customers.
                                    <ui:repeat id="customersList" value="#{adminService.currentCustomerPage}" var="customer">
                                        <f:subview id="editCustomer#{customer.id}">
                                            <p class="#{adminService.getEditCustomerClass(customer.id)}">
                                                <h:inputText id="email#{customer.id}" value="#{adminService.customerEmail}"/><br/>
                                                <h:inputText id="firstName#{customer.id}" value="#{adminService.customerFirstName}"/>
                                                <h:inputText id="lastName#{customer.id}" value="#{adminService.customerLastName}"/><br/>
                                                <h:commandButton id="saveEdit#{customer.id}" type="submit" value="Save" actionListener="#{adminService.saveCustomer()}">
                                                    <f:ajax render="@form" event="click" execute="@form"/>
                                                </h:commandButton>
                                                <h:commandButton id="cancelEdit#{customer.id}" type="submit" value="Cancel" actionListener="#{adminService.cancelEdit()}">
                                                    <f:ajax render="@form" event="click" execute="@form" />
                                                </h:commandButton>
                                            </p>
                                        </f:subview>
                                        <f:subview id="viewCustomer#{customer.id}">
                                            <p class="#{adminService.getViewCustomerClass(customer.id)}">
                                                #{customer.email}<br/>
                                                #{customer.firstName} #{customer.lastName}<br/>
                                                <h:commandLink id="suggestion" target="_blank" value="View Suggestions" action="/Admin/customersuggestions">
                                                    <f:param name="user" value="#{customer.id}"/>
                                                </h:commandLink>
                                                <h:commandButton id="edit" type="submit" value="Edit" action="#{adminService.editCustomer(customer)}">
                                                    <f:ajax render="@form" event="click" execute="@form" />
                                                </h:commandButton>
                                            </p>
                                        </f:subview>
                                        <br/>
                                    </ui:repeat>
                                </span>
                            </f:subview>
                        </div>
                    </f:subview>
                </h:form>
            </div>
        </div>
    </h:body>
</html>
4

2 に答える 2

1

私は答えを見つけました、そしてその原因は本当にかなり奇妙ですが、それは理にかなっています.

私のIDでは、ELを使用してUIComponentsの一意のIDを定義していました(これは必要ありませんでしたが)。ID から EL を削除すると、ajax が機能します。

私は推測しています (BalusC の方がより完全な回答を提供すると確信していますが)、ID が静的ではないため、ID の概念は同じであっても、JSF が UIComponents を見つける方法に影響していたのです。

余分な要素を追加しなければ、問題は完全に回避できたので、今はばかげているように感じます。

たとえば、元の投稿のコードは次のようになります。

<h:form id="adminPanel">
...
<f:subview id="editCustomer">
    <p class="#{adminService.getEditCustomerClass(customer.id)}">
        <h:inputText id="email" value="#{adminService.customerEmail}"/><br/>
        <h:inputText id="firstName" value="#{adminService.customerFirstName}"/>
        <h:inputText id="lastName" value="#{adminService.customerLastName}"/><br/>
        <h:commandButton id="saveEdit" type="button" value="Save">
            <f:ajax render="@form" event="click" listener="#{adminService.saveCustomer()}"/>
        </h:commandButton>
        <h:commandButton id="cancelEdit" type="button" value="Cancel">
            <f:ajax render="@form" event="click" listener="#{adminService.cancelEdit()}"/>
        </h:commandButton>
    </p>
</f:subview>
...
</h:form>
于 2013-05-03T23:22:21.680 に答える
0

Javascript イベント onclick でフォームを送信する理由はありますか? 次のようにアクションを呼び出すことをお勧めします。

<h:commandButton id="saveEdit#{customer.id}" value="Submit" actionListener="#{adminService.saveCustomer()}">
    <f:ajax render="@form" execute="@form"/>
</h:commandButton>
于 2013-05-03T10:59:23.130 に答える