5

我正在尝试实现一个用户名列表,可以通过单击UPDOWN链接重新排列。

<ul>
    <ui:repeat var="user" value="#{cc.attrs.value}">
        <li>
            #{user.name}
            <h:link outcome = "user" value = "left" onclick="#{accountController.moveDown}">
                <f:param name="id" value = "${user.id}" />
            </h:link>
        </li>

    </ui:repeat>
</ul>

这里的问题是我似乎没有正确使用 onclick 属性。这样做的正确方法是什么?


编辑:按照您的建议,我将所有链接放在一个表格中:

<h:form>
        <ui:repeat value="#{cc.attrs.value}" var = "user">
        <div class = "user">
            <h:commandLink id = "Link1" value = "Up" binding = "#{accountController.ommandLink}" action = "#{accountController.moveUserUp}">
                <f:attribute name = "userId" value = "#{user.id}" />
            </h:commandLink>
            <h:commandLink id = "Link2" value = "Down" binding = "#{accountController.commandLink}" action = "#{accountController.moveUserDown}">
                <f:attribute name = "userId" value = "#{user.id}" />
            </h:commandLink>
            <h:commandLink id = "Link3" value = "Delete" binding = "#{accountController.commandLink}" action = "#{accountController.deleteUser}">
                <f:attribute name = "userId" value = "#{user.id}" />
            </h:commandLink>
    </div>
</h:form>

托管 Bean:

private UIComponent commandLink;

public void moveUserUp(){
    Integer userId = (Integer)commandLink.getAttributes().get("userId");
    System.out.println("MOVE TAB LEFT :" + userId);
}

public void moveUserDown(){
    Integer userId = (Integer)commandLink.getAttributes().get("userId");
    System.out.println("MOVE TAB RIGHT: " + userId);
}

public void deleteUser(){
    Integer userId = (Integer)commandLink.getAttributes().get("userId");
    System.out.println("DELETE TAB: " + userId);
}

public UIComponent getCommandLink() {
    return commandLink;
}

public void setCommandLink(UIComponent commandLink) {
    this.commandLink = commandLink;
}

命令链接和托管 bean 之间的通信正在工作,但在 UI 中只显示最后一个命令链接(关闭操作)。

4

3 回答 3

14

为了在单击链接时调用 bean 操作方法,您需要<h:commandLink>. 这必须包含在<h:form>.

<h:form>
    <h:commandLink ... action="#{bean.action}" />
</h:form>

public String action() {
    // ...

    return "/other.xhtml";
}

在 JSF 中,只有将EL 表达式解释为 a的属性MethodExpression才能用于声明操作方法。当 JSF 生成 HTML 输出时,所有其他属性都被解释为ValueExpression并立即执行。这涵盖了onclick属性,其值实际上应该代表一个 JavaScript 函数。

如果您确实想使用 GET 链接,则将操作方法​​移动到<f:viewAction>目标页面中的 a。这将在目标页面的页面加载时调用。

<h:link ... outcome="/other.xhtml" />

<f:metadata>
    <f:viewAction action="#{bean.onload}" />
</f:metadata>

public void onload() {
    // ...
}

也可以看看:


按照您的建议,我将所有链接放在一个表格中

命令链接和托管 bean 之间的通信正在工作,但在 UI 中只显示最后一个命令链接(关闭操作)。

您不应将多个物理上不同的组件绑定到一个相同的 bean 属性。此外<f:attribute>,在 JSF2 中,传递参数也是 hacky 并且不再需要。假设您使用的是 Servlet 3.0 / EL 2.2 容器(您的问题历史证实您使用的是 Glassfish 3),而不是直接将参数作为方法参数传递:

<h:commandLink id="Link1" value="Up" action="#{accountController.moveUserUp(user)}" />
<h:commandLink id="Link2" value="Down" action="#{accountController.moveUserDown(user)}" />
<h:commandLink id="Link3" value="Delete" action="#{accountController.deleteUser(user)}" />

public void moveUserUp(User user) {
    // ...
}

public void moveUserDown(User user) {
    // ...
}

public void deleteUser(User user) {
    // ...
}

也可以看看:

于 2012-01-12T11:49:39.537 回答
3

onclick属性用于调用 JavaScript 函数(客户端)。当您想要附加 JavaScript 点击事件处理程序时使用它。

"#{accountController.moveDown}"是一个方法表达式。顾名思义,它看起来像是accountController一个托管 bean。

正如h:link文档所说:

javax.el.ValueExpression(必须评估为 java.lang.String)

可以是最终必须计算为字符串的值表达式。

在此元素上单击指针按钮时执行的 Javascript 代码。

更新:

可能是你正在寻找的是h:commandLink。您可以使用该action属性来调用支持 bean 方法。

于 2012-01-11T20:03:11.730 回答
1
I have modified your code, let me know if this is what you are looking at achive

    <h:form>
        <a4j:outputPanel id="userList" ajaxRendered="false">
            <ui:repeat  value="#{manageUser.userList}" var="user">
                <div class="user">
                    <h:panelGrid columns="3">
                    <h:outputText value="#{user.userId} ---- #{user.userName} ---- " />

                    <a4j:commandLink id="LinkUp" value="Up" execute="@this" 
                        action="#{manageUser.moveUserUp}" limitRender="true" render="userList" >
                        <f:setPropertyActionListener value="#{user}" target="#{manageUser.user}" />
                    </a4j:commandLink>

                    <a4j:commandLink id="LinkDown" value="down"
                        action="#{manageUser.moveUserDown}" execute="@this" limitRender="true" render="userList" >
                        <f:setPropertyActionListener value="#{user}" target="#{manageUser.user}" />
                    </a4j:commandLink>
                    </h:panelGrid>
                </div>
            </ui:repeat>
        </a4j:outputPanel>      
        </h:form>

Managed Beans (ManageUser)


import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean(name="manageUser")
@ViewScoped
public class ManageUser  implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -5338764155023244249L;

    private List<UserBean> userList;

    private UserBean user;

    /**
     * @return the user
     */
    public UserBean getUser() {

        return user;
    }

    /**
     * @param user the user to set
     */
    public void setUser(UserBean user) {
        this.user = user;
    }


    /**
     * @return the userList
     */
    public List<UserBean> getUserList() {
        return userList;
    }

    /**
     * @param userList the userList to set
     */
    public void setUserList(List<UserBean> userList) {
        this.userList = userList;
    }

    public ManageUser() {
        UserBean user1= new UserBean();
        user1.setUserId("1");
        user1.setUserName("userName1");

        UserBean user2= new UserBean();
        user2.setUserId("2");
        user2.setUserName("userName2");

        UserBean user3= new UserBean();
        user3.setUserId("3");
        user3.setUserName("userName3");

        userList = new ArrayList<UserBean>();
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
    }

    public void moveUserDown(){

        if(user !=null){
            int indexObj= userList.indexOf(user);

            if(indexObj < userList.size()-1){
                UserBean tempUser=userList.get(indexObj+1);
                userList.set(indexObj+1, user);
                userList.set(indexObj, tempUser);

            }
        }
    }

    public void moveUserUp(){

        if(user !=null){
            int indexObj= userList.indexOf(user);

            if(indexObj > 0){
                UserBean tempUser=userList.get(indexObj-1);
                userList.set(indexObj-1, user);
                userList.set(indexObj, tempUser);

            }
        }
    }

}

UserBean
import java.io.Serializable;

public class UserBean  implements Serializable {



    /**
     * 
     */
    private static final long serialVersionUID = 3820279264217591645L;

    private String userName;

    private String userId;

    /**
     * @return the userName
     */
    public String getUserName() {
        return userName;
    }

    /**
     * @param userName the userName to set
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * @return the userId
     */
    public String getUserId() {
        return userId;
    }

    /**
     * @param userId the userId to set
     */
    public void setUserId(String userId) {
        this.userId = userId;
    }

}
于 2012-01-12T19:34:51.027 回答