JSF Action Méthode n'est pas appelée
J'ai une vue JSF avec un Primefaces tableau de données et un bouton de commande insite, comme la jachère:
<p:messages id="statusMessages" showDetail="true" />
<h:form id="listForm">
<p:panel header="Wellsite List">
<br />
<h:outputLabel value="Welcome, #{wellsiteController.loggedUser.login}" />
<br />
<br />
<p:dataTable id="dataTable" var="wellsite" value="#{wellsiteController.wellsiteDataTableModel}"
paginator="true" rows="10" selection="#{wellsiteController.wellsite}">
<p:column selectionMode="single" style="width:18px" id="radioSelect" />
<p:column sortBy="#{wellsite.reference}" headerText="Wellsite ID">
<h:outputText value="#{wellsite.reference}" />
</p:column>
<p:column headerText="Allowed Groups">
<h:outputText value="#{wellsite.allowedGroups.toString()}" />
</p:column>
<f:facet name="footer">
<h:panelGrid columns="3">
<p:commandButton id="addWellsite" value="Add New Wellsite" icon="ui-icon-flag" ajax="false" action="#{wellsiteController.showAddWellsite}"/>
<p:commandButton id="editWellsite" value="Edit Selected Wellsite" icon="ui-icon-wrench" ajax="false" action="#{wellsiteController.showEditWellsite}"/>
<p:commandButton id="deleteWellsiteButton" value="Remove Selected Wellsite" icon="ui-icon-trash" onclick="confirmation.show()" type="button"/>
</h:panelGrid>
</f:facet>
</p:dataTable>
<p:spacer height="20" />
</p:panel>
<p:confirmDialog id="confirmDialog" message="Are you sure you want to remove the selected Wellsite along with all it's data?" header="Confirmation" severity="alert" widgetVar="confirmation">
<p:commandButton id="confirm" value="Yes" ajax="false" oncomplete="confirmation.hide()" action="#{wellsiteController.deleteWellsite}" />
<p:commandButton id="decline" value="Cancel" onclick="confirmation.hide()" type="button" />
</p:confirmDialog>
</h:form>
Et voici le contrôleur:
@ManagedBean(name = "wellsiteController")
@RequestScoped
public class WellsiteController implements Serializable {
private static final long serialVersionUID = 1L;
@ManagedProperty("#{wellsiteDao}")
private WellsiteDao wellsiteDao;
@ManagedProperty("#{userDao}")
private UserDao userDao;
@ManagedProperty("#{groupDao}")
private GroupDao groupDao;
@ManagedProperty("#{userController.loggedUser}")
private UserEnt loggedUser;
private WellsiteEnt wellsite;
private List<WellsiteEnt> wellsiteList;
DualListModel<GroupEnt> pickGroupsModel;
public WellsiteController(){
}
@PostConstruct
public void build(){
wellsite = new WellsiteEnt();
wellsite.setAllowedGroups(new ArrayList<GroupEnt>());
}
/*some getters & setters*/
public WellsiteDataTableModel getWellsiteDataTableModel(){
return new WellsiteDataTableModel(getWellsiteList());
}
public void setPickGroupsModel(DualListModel<GroupEnt> model){
pickGroupsModel = model;
}
public DualListModel<GroupEnt> getPickGroupsModel() {
if(pickGroupsModel == null){
List<GroupEnt> allGroups = groupDao.getAll();
List<GroupEnt> currentGroups = wellsite.getAllowedGroups();
for(GroupEnt g : currentGroups){
allGroups.remove(g);
}
pickGroupsModel = new DualListModel<GroupEnt>(allGroups, currentGroups);
}
return pickGroupsModel;
}
public String listWellsites(){
getWellsiteList();
return "listWellsites";
}
public String showAddWellsite(){
FacesContext context = FacesContext.getCurrentInstance();
setWellsite(new WellsiteEnt());
wellsite.setAllowedGroups(new ArrayList<GroupEnt>());
pickGroupsModel = null;
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,
"Fields annotated with a ' * ' are mandatory",""));
return "addWellsite";
}
public String addWellsite(){
FacesContext context = FacesContext.getCurrentInstance();
wellsite.setDate(new Date());
wellsite.setLastUpdate(wellsite.getDate());
try {
wellsiteDao.addWell(wellsite);
for(GroupEnt g : pickGroupsModel.getTarget()){
GroupEnt group = groupDao.getOne(g.getGroupId());
group.getGroupWellsites().add(wellsite);
groupDao.update(group);
}
return listWellsites();
} catch (Exception ex) {
Logger.getLogger(WellsiteController.class.getName()).log(Level.SEVERE, null, ex);
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
ex.getMessage(),""));
return null;
}
}
}
Ce point de vue est rendu correctement. La datatable et les boutons a l'air bien. Le problème est que quand je clique sur le "addWellsite" bouton de commande, rien ne se passe. La page semble juste pour se rafraîchir. Si je clique à nouveau, comme l'exception qui se passe:
java.lang.NumberFormatException: For input string: "null"
À l'aide d'un débogueur, j'ai découvert que le "addWellsite"l'action n'est PAS la première fois, et donc, pas de générer des résultats (ainsi, l'actualisation de la page).
L'exception est probablement à venir de l'absence d'initialisation dans le courant ou la cible de points de vue (puisque les deux sont affichés à partir de méthodes d'action qui n'ont pas été appelés à l'actualisation de la page)
La question est: POURQUOI la méthode de l'action n'est pas la première fois?
Que de cette réponse:
Chaque fois qu'un
UICommand
composant ne parvient pas à invoquer l'action associée, vérifiez les éléments suivants:
UICommand
les composants doivent être placés à l'intérieur d'unUIForm
composant (par exemple,h:form
).
J'ai un h:formulaire
- Vous ne pouvez pas nid plusieurs
UIForm
composants les uns dans les autres (attention à l'inclure des fichiers!).
Il n'y a qu'un seul.
- Pas de validation/erreur de conversion doit avoir été produite (utiliser
h:messages
pour tous).
J'ai un h:les messages qui n'affiche aucune erreur.
- Si
UICommand
les composants sont placés à l'intérieur d'unUIData
composant, veiller à ce que exactement la mêmeDataModel
(l'objet derrière leUIData
'svalue
attribut) est préservée.
Le bouton de commande est à l'intérieur de la dataTable, mais la vue cible n'a pas besoin du modèle de données. Que mon contrôleur montre le code, l'objet est construit comme le point de vue tente de restauration. La requête suivante n'est pas à l'aide de cette table, je ne sais pas gérer plus.
- La
rendered
etdisabled
attributs du composant et tous les composants parent ne doit pas évaluer àfalse
cours d'appliquer les valeurs de demande de phase.
Il n'y a pas rendered
ou disbled
attributs.
- Assurez-vous qu'aucun
PhaseListener
ou toutEventListener
dans la requête-réponse de la chaîne a changé la JSF le cycle de vie d'ignorer l'invoquer la phase d'action.
Pas phaseListener est défini.
- Assurez-vous qu'aucun
Filter
ouServlet
dans la même requête-réponse de la chaîne a bloqué la demande fo leFacesServlet
en quelque sorte.
Aucune autre Servlet est défini. Je ne sais même pas ce qu'est un Filtre.
POURQUOI la méthode de l'action n'est pas la première fois?
Je me suis rendu par un non-ajax méthode d'action.
Êtes-vous sûr? Si il s'agissait d'une requête ajax, puis j'ai pu expliquer le problème.
La requête ajax devrait inclure explicitement l'ID du formulaire
:listForm
dans le render
attribut (ou update
en cas de PrimeFaces).Il était. Putain! Êtes-vous un compilateur ou quelque chose?
OriginalL'auteur Pedro Peixoto | 2012-05-14
Vous devez vous connecter pour publier un commentaire.
Cela peut se produire lorsque l'un des parents de ce
<h:form>
a été rendue par une requête ajax initiée par un autre<h:form>
à l'avance. Le rendu/mis à jour<h:form>
perdrait alors de son état d'affichage. Cela est dû à un bogue dans le code JavaScript de l'API, comme décrit dans JSF question 790 qui est déjà fixé pour le peu de temps à venir JSF 2.2.En attendant, avec la JSF 2.0/2.1, vous devez explicltly spécifier l'ID du client de la
<h:form>
dans lerender
(ou de PrimeFaces, leupdate
) attribut de l'action dans l'autre forme.E. g.
ou
Ou tout simplement faire un normal (non-ajax) demande à la place.
Voir aussi:
Peut aussi 🙂 Vous êtes les bienvenus.
OriginalL'auteur BalusC