Come invocare un metodo di azione bean utilizzando un collegamento? L'onclick non funziona
-
27-10-2019 - |
Domanda
Sto cercando di implementare un elenco di nomi degli utenti che possono essere riorganizzate cliccando su UP o GIU ' link.
<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>
Il problema qui è che sembra che non sto usando correttamente l'attributo onclick. Qual è il modo corretto per fare questo?
Modifica In seguito i vostri consigli ho messo tutti i link in una forma:
<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 Managed:
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;
}
La comunicazione tra il comando Link e il bean gestito funziona, ma nell'interfaccia utente viene visualizzato solo l'ultimo commandLink (vicino all'azione).
Soluzione
Al fine di invocare un metodo di azione di fagioli al clic di un collegamento, è necessario <h:commandLink>
. Questo deve essere racchiuso in un <h:form>
.
<h:form>
<h:commandLink ... action="#{bean.action}" />
</h:form>
public String action() {
// ...
return "/other.xhtml";
}
In JSF, solo il attributi che interpretano l'espressione EL come MethodExpression
può essere utilizzato per dichiarare metodi d'azione. Tutti gli altri attributi vengono interpretati come ValueExpression
e sono immediatamente eseguito quando l'output HTML è generato da JSF. Questo copre l'attributo onclick
, il cui valore dovrebbe in realtà rappresentare una funzione JavaScript.
Nel caso in cui si vuole realmente utilizzare un collegamento GET, quindi spostare il metodo di azione per un <f:viewAction>
nella pagina di destinazione. Questo sarà invocato a pagina di caricamento della pagina di destinazione.
<h:link ... outcome="/other.xhtml" />
<f:metadata>
<f:viewAction action="#{bean.onload}" />
</f:metadata>
public void onload() {
// ...
}
Vedi anche:
- Quando devo usare h: outputLink anziché h: commandLink?
- Come inviare formare valori di ingresso e richiamare un metodo in JSF fagiolo
- Come faccio ad elaborare GET di query parametri URL stringa in backing bean al caricamento della pagina?
- Come navigare in JSF? Come rendere URL riflettere pagina corrente (e non precedente)
In seguito i vostri consigli ho messo tutti i link in una forma
La comunicazione tra il comando Link e il bean gestito sta lavorando, ma nell'interfaccia utente solo l'ultima commandLink (vicino all'azione) viene visualizzato.
Non si dovrebbe impegnare più componenti fisicamente diverse per una stessa proprietà e fagioli. Anche il <f:attribute>
per passare argomenti è hacky e non più necessario in JSF2. Supponendo che si sta utilizzando un 2,2 contenitore di Servlet 3.0 / EL (i tuoi conferma cronologia domanda che si sta utilizzando Glassfish 3), piuttosto solo passare l'argomento come metodo di argomento direttamente:
<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)}" />
con
public void moveUserUp(User user) {
// ...
}
public void moveUserDown(User user) {
// ...
}
public void deleteUser(User user) {
// ...
}
Vedi anche:
Altri suggerimenti
L'attributo onclick
viene utilizzato per richiamare la funzione JavaScript (lato client). E 'da utilizzare quando si desidera allegare un JavaScript hanlder evento click.
"#{accountController.moveDown}"
è un metodo di espressione. E come suggerisce il nome assomiglia accountController
è un bean gestito.
h:link
doc dice:
javax.el.ValueExpression (deve essere valutata come java.lang.String)
può essere un'espressione di valore che in ultima analisi deve essere valutata come una stringa.
codice Javascript eseguito quando un pulsante del puntatore si fa clic su questo elemento.
Aggiornamento:
Può essere quello che stai cercando è h:commandLink
. È possibile utilizzare l'attributo action
per richiamare il metodo supporto di fagioli.
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;
}
}