2010-01-27 7 views
2

Je dois créer des commandLinks de manière dynamique et y attacher un programme d'écoute d'action, j'ai donc mis sur la page JSP et utilisé un tel code pour ajouter les commandLinks et pour assigner une action auditeurs:JSF: Comment attacher une actionListener au composant créé par programme

public ManagedBean(){ 
List<UIComponenet> child = panelGrid.getChilderen(); 
list.clear(); 

List<MyClass> myList = getSomeList(); 

for (MyClass myObj : myList){ 
    FacesContext ctx = FacesContext.getCurrentContext(); 
    HtmlCommandLink cmdLink = (HtmlCommandLink) ctx.getApplication.createComponent(HtmlCommandLink.COMPONENT_TYPE); 
    cmdLink.setValue(myObj.getName()); 
    cmdLink.setActionLinstner(new ActionListener(){ 
    public void processAction(ActionEvent event) throws AbortProcessingException{ 
     System.out.println (">>>>>>>>>>>>>>>>>I am HERE "); 
    } 
    }); 
    child.add(cmdLink); 
} 
} 

Mais malheureusement, quand je presse cette commandLinks, lance une exception! Pourriez-vous m'aider s'il vous plaît comment ajouter des écouteurs d'événement de componenet à l'exécution?

(Note, le code ci-dessus mes contiennent des erreurs de syntaxe/compilation que je viens d'écrire)

+0

Quelle est l'exception? – Drew

+0

Vous n'avez pas la trace de pile en ce moment, mais est-ce censé fonctionner? –

Répondre

11

D'abord, vous devez assigner manuellement ID à tout UINamingContainer, UIInput et UICommand dynamiquement créé des composants. Sinon, JSF ne peut pas les localiser dans l'arborescence des composants en fonction des paramètres de la requête, car ils ne correspondent pas aux ID générés automatiquement.

Ainsi, au moins faire:

HtmlCommandLink link = new HtmlCommandLink(); 
link.setId("linkId"); 
// ... 

Deuxièmement, vous êtes censé créer un ActionListener comme MethodExpression comme suit:

FacesContext context = FacesContext.getCurrentInstance(); 
MethodExpression methodExpression = context.getApplication().getExpressionFactory().createMethodExpression(
    context.getELContext(), "#{bean.actionListener}", null, new Class[] { ActionEvent.class }); 

link.addActionListener(new MethodExpressionActionListener(methodExpression)); 
// ... 

... et bien sûr avoir la méthode suivante la classe de grain de support derrière #{bean}:

public void actionListener(ActionEvent event) { 
    // ... 
} 

Toutes les choses dynamiques ci-dessus ne fondamentalement la même que la balise JSF brute suivante:

<h:commandLink id="linkId" actionListener="#{bean.actionListener}" /> 
+0

Bravo, merci beaucoup :) Mais j'ai remarqué que, le premier clic sur n'importe quel lien de commande ne fonctionne pas, seulement à partir du deuxième clic le début de l'écouteur en invocation. –

+0

Donner à tous les parents 'UINamingContainer' (par exemple' UIForm', 'UIData', etc) éléments un ** fixe ** ID (soit dynamiquement ou statiquement) et ** ne pas ** utiliser MyFaces/Tomahawk' prependId = "false" '- si utilisé. – BalusC

+0

@BalusC que faire si j'ai un bouton UIComponent = viewRoot.findComponent ("save"); ? Comment ajouter une actionListener à cela? Est-ce que j'utilise toujours MethodExpression? Il me demande que je dois lancer à UICommand mais je reçois une erreur – Erick

1

J'ai eu le même problème. Les composants transitoires ne fonctionnent pas avec les actionListeners. Ne pas appeler

FacesContext.getCurrentInstance().getViewRoot().setTransient(true); ou component.setTransient(true);

Dès que je l'ai enlevé, il était OK.

Questions connexes