2016-04-03 7 views
3

Ich habe ein logic:iterate in einem logic:iterate. Ich kann alle Felder in dieser Tabelle bearbeiten. Für jede logic:iterate habe ich eine getXXX Zeilenmethode.Streben 1 - Iteration in Iteration - innere Reihe Methode

Zuerst klicke ich auf meinen'add'-Knopf. Die Iteration wurde mit 3 Personen gefüllt. Zuerst eine Adresse, die zweite zwei und die dritte drei. (In der realen Anwendung ist es dynamisch)

Jetzt ändere ich einige Eingabefelder und klicke auf meine Senden-Schaltfläche. Jetzt werden die Zeilenmethoden aufgerufen, um den alten Zustand zu initialisieren. Aber wie implementiere ich die Zeilenadressenmethode richtig? Es wird nur dreimal aufgerufen, aber ich muss die Personenfelder genau ausfüllen und zurückbekommen, oder?

Hoffe es ist eine bessere Beschreibung für mein Problem als im letzten Thread.

EDIT: Versuchen Sie es besser zu erklären. Ich habe eine Personlist und in meiner getRowPerson-Methode gibt es kein Problem, da der "Index" nur aus dieser Liste ist. ABER ich habe jetzt in diesem Beispiel drei Adresslisten, ich kann nicht sagen welche "Liste" die getRowAdresse aufruft. (An dieser Stelle muss ich eine Adresse von der richtigen Person mit dem richtigen Index zurückgeben, aber ich kenne die Person nur die Position in Adressliste)

Wenn die getRowAdress in der Personenklasse waren, ist es auch anders, aber dort es hat nie angerufen.

Das andere Problem ist, dass die getRowAdress nur dreimal genannt wird, meiner Meinung nach, sollte ich einmal für jede Adresse Zeile Artikel genannt werden. Für mein Beispiel sechs Mal. Ich denke, mit der inneren Iteration stimmt etwas nicht. Ich habe versucht, verschachtelt: Iteration aber funktioniert auch nicht.

Console:

adress index2<br> 
adress index1<br> 
adress index0<br> 
person index1<br> 
person index2<br> 
person index0<br> 

Html:

<logic:iterate id="rowPerson" name="iterateForm" indexId="rowIndex" property="persons" > 
    <html:text name="rowPerson" property="name" indexed="true"/> 
    <logic:iterate id="rowAdress" name="rowPerson" indexId="rowAdressIndex" property="address" > 
     <html:text name="rowAdress" property="addressname" indexed="true"/> 
    </logic:iterate> 
    <br> 
</logic:iterate> 
<html:submit value="Send" property="submitvalue"/> 
<html:submit value="Add" property="submitvalue"/> 
</html:form> 

Aktion

public class HelloWorldAction extends Action { 

    @Override 
    public ActionForward execute(ActionMapping mapping, ActionForm form, 
      HttpServletRequest request, HttpServletResponse response) throws Exception { 
     HelloWorldForm helloWorldForm = (HelloWorldForm) form; 
     String submitvalue = request.getParameter("submitvalue"); 
     if (submitvalue == null) { 
      return mapping.findForward("success"); 
     } else if ("Add".equals(submitvalue)) { 
      for (int i = 0; i < 3; i++) { 
       PersonForm person = new PersonForm(); 
       person.setName("Person " + i); 
       for(int y = 0 ; y <= i ; y++){ 
        AddressForm add = new AddressForm(); 
        add.setAddressname("Adress" + y); 
        person.getAddress().add(add); 
       } 
       helloWorldForm.getPersons().add(person); 
      }     

     } 
     return mapping.findForward("success"); 
    } 
} 

ActionForm-

public class HelloWorldForm extends ActionForm{ 
    private static final long serialVersionUID = -473562596852452021L; 

    private List<PersonForm> persons = new ArrayList<>(); 

    public PersonForm getRowPerson(int index){  
     System.out.println("person index" + index); 
     while(persons.size() <= index){ 
      persons.add(new PersonForm()); 
     }   
     return persons.get(index); 
    } 

    public AddressForm getRowAdress(int index){ 
     System.out.println("adress index" + index); 
     // ???? dont know ??? 
     return new AddressForm(); 
    } 

    public List<PersonForm> getPersons() { 
     return persons; 
    } 

    public void setPersons(List<PersonForm> persons) { 
     this.persons = persons; 
    } 
} 

Personform und Address haben nur Setter & Getter

+0

Die Frage sieht etwas verwirrend aus. Können Sie weitere Details hinzufügen oder die Frage anders formulieren? Besonders konnte ich nicht bekommen, wenn Sie sagen, wie ich die Zeilenadressmethode richtig implementiere? Es wird nur dreimal aufgerufen, aber ich muss genau die Personenfelder ausfüllen und sie zurückbekommen, oder? ' –

+0

ich bearbeite meine Frage hoffe es hilft – pL4Gu33

Antwort

1

Ihre JSP rendert HTML-Code:

<input type="text" name="rowPerson[0].name" value="Person 0">  
<input type="text" name="rowAdress[0].addressname" value="Adress0"> 

Dies löst Anrufe getRowPerson(0) und getRowAdress(0) in Ihrem HelloWorldForm.Aber wir wollen eigentlich zu nisten die Elemente, und dafür müssen wir die nested Tag-Bibliothek verwenden:

<nested:iterate property="persons"> 
    <nested:text property="name"/> 
    <nested:iterate property="address"> 
     <nested:text property="addressname"/> 
    </nested:iterate> 
    <br> 
</nested:iterate> 

Dies erzeugt:

<input type="text" name="persons[0].name" value="Person 0"> 
<input type="text" name="persons[0].address[0].addressname" value="Adress0"> 

Nach dem gleichen Verfahren aus zu lesen und in die Listen vereinfacht schreiben die Lösung. Wenn die scope in Ihrer Aktion auf session festgelegt ist, was der Standardwert ist, werden die Werte nach dem Senden in Ihrem Formular überschrieben, und Sie müssen sich keine Gedanken über das dynamische Anwachsen der Listen machen. Sie können einfach haben:

public class HelloWorldForm extends ActionForm{ 
    private List<PersonForm> persons = new ArrayList<>(); 

    public List<PersonForm> getPersons() { 
     return persons; 
    } 
    public void setPersons(List<PersonForm> persons) { 
     this.persons = persons; 
    } 
} 

Andernfalls, wenn Sie scope="request" in Ihrer Aktion Mapping haben, in der struts-config.xml, müssen Sie die Listen dynamisch neu erstellen. Dazu wird mit einer Option, die commons-Sammlung LazyList:

public class HelloWorldForm extends ActionForm { 
    private final Factory personFactory = new Factory() { 
     @Override public Object create() { return new PersonForm(); } 
    }; 
    // commons-collection 4 offers a LazyList<E> with generics 
    private List lazyPersons = LazyList.decorate(new ArrayList(), personFactory); 

    public List<PersonForm> getPersons() { 
     return lazyPersons; 
    } 
    public void setPersons(List<PersonForm> persons) { 
     this.lazyPersons = LazyList.decorate(persons, personFactory); 
    } 
} 

(implementieren Code wie oben für PersonForm auch)

dynamisch wachsende Listen Needing ist ein übliches Struts Problem. Hier ist ein Katalog von Lösungen für diese, wenn Sie weiter lesen möchten: http://wiki.apache.org/struts/StrutsCatalogLazyList

+0

danke für deine Antwort der Link ist nett :) aber beide meiner Zeilenmethoden heißen . Die Personliste funktioniert gut damit. Wenn ich die rowAddress zu PersonForm verschiebe, wird sie nie aufgerufen. Wenn ich es (Ihre Lösung) umbenenne, werden beide nie als afaik bezeichnet. Ich muss den 'id =" rowPerson "' Namen für die Indexmethode verwenden. Eine weitere Information: Die Adresszeilenmethode wurde nur 3 Mal aufgerufen. Es fühlt sich an, dass die "innere" Liste nicht für eine spezielle Person "indexiert" wird. Ich denke, die Methodennamen sind richtig – pL4Gu33

+0

@ pL4Gu33, hab es. Die Antwort wurde aktualisiert. – ericbn

+0

Danke !!! :) Bounty kommt in 1 Stunde – pL4Gu33