我正在尝试实施一个用户名列表,可以通过点击 UP 或 DOWN 链接重新排列。
<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>
Managed 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;
}
命令Link和托管bean之间的通信正在运行,但在UI中只显示最后一个commandLink(关闭操作)。
答案 0 :(得分:12)
要在点击链接时调用bean操作方法,您需要<h:commandLink>
。必须将其括在<h:form>
。
<h:form>
<h:commandLink ... action="#{bean.action}" />
</h:form>
public String action() {
// ...
return "/other.xhtml";
}
在JSF中,只有将attributes解释为EL表达式的MethodExpression
才能用于声明操作方法。所有其他属性都被解释为ValueExpression
,并且在JSF生成HTML输出时立即执行它们。这包含onclick
属性,其值实际上应代表JavaScript函数。
如果您确实想要使用GET链接,请将操作方法移至目标页面中的<f:viewAction>
。这将在目标页面的页面加载时调用。
<h:link ... outcome="/other.xhtml" />
<f:metadata>
<f:viewAction action="#{bean.onload}" />
</f:metadata>
public void onload() {
// ...
}
根据您的建议,我将所有链接放在
中命令Link和托管bean之间的通信正在运行,但在UI中只显示最后一个commandLink(关闭操作)。
您不应将多个物理上不同的组件绑定到同一个bean属性。此外,传递参数的<f:attribute>
是hacky,在JSF2中不再需要。假设您正在使用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) {
// ...
}
答案 1 :(得分:3)
onclick
属性用于调用JavaScript函数(客户端)。当您想要附加JavaScript click事件hanlder时,可以使用它。
"#{accountController.moveDown}"
是一个方法表达式。顾名思义,accountController
看起来像是一个托管bean。
正如h:link
doc所说:
javax.el.ValueExpression(必须求值为java.lang.String)
可以是必须最终评估为字符串的值表达式。
在此元素上单击指针按钮时执行的Javascript代码。
<强>更新强>
您所寻找的可能是h:commandLink
。您可以使用action
属性来调用辅助bean方法。
答案 2 :(得分: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;
}
}