2017-12-27 5 views
1

Ich habe Probleme beim Übergeben der Formulareingabe an ein Attribut eines verschachtelten Objekts (object.subobject.property). Spezifisch habe ich ein Institution institution Objekt, das ein Country country Objekt enthält, das ein Attribut hat, das countryName genannt wird, auf wie institution.country.getCountryName() zugegriffen, aber ich kann nicht die Model erhalten, die richtig nach Formularvorlage ausgefüllt wird. Im Folgenden habe ich drei Druckanweisungen während der @PostMapping. Das Ergebnis sieht wie:Verwenden eines Thymeleaf-Formulars zum Erstellen der POST-Anforderung

Institution(instId=398, instName=Alfred Wegener Institute for Polar and Marine Research, abbrvName=AWI, country=null, action=finish institution edit) 
{modelinstitution=Institution(instId=398, instName=Alfred Wegener Institute for Polar and Marine Research, abbrvName=AWI, country=null, action=finish institution edit), org.springframework.validation.BindingResult.modelinstitution=org.springframework.validation.BeanPropertyBindingResult: 0 errors} 
org.springframework.validation.BeanPropertyBindingResult: 0 errors 

Beachten Sie, wie die Werte für country= sind null sowohl in den Model und das institutionAttributes Objekt. Ich habe erwartet, etwas mehr wie

country=Country(countryName=United States, countryId=12, parentCountry=) 

Warum ist das Formular nicht das Country Objekt bevölkert und wie kann ich es mache das tun?

Ich habe ein Formular:

<form id="lead_form" data-toggle="validator" th:action="@{/institutions}" th:object="${institution}" method="post" enctype="application/x-www-form-urlencoded"> 
    <input type="hidden" id="action" name="action" value="finish institution edit"/> 
    <input type="hidden" id="instId" name="instId" th:value="${institution.instId}"/> 

    <div class="row"> 
     <div class="col-md-2 text-left"> 
      <label for="instIdDisplay" class="control-label">Institution ID: </label> 
      <input class="form-control border-input" th:value="${institution.instId}" id="instIdDisplay" name="instIdDisplay" type="number" disabled="true"/> 
     </div> 
     <div class="col-md-5 text-left"> 
      <label for="instName" class="control-label">Institution Name: </label> 
      <input class="form-control border-input" th:value="${institution.instName}" placeholder="Required" id="instName" name="instName" type="text" required="true"/> 
     </div> 
     <div class="col-md-2 text-left"> 
      <label for="abbrvName" class="control-label">Abbreviation: </label> 
      <input class="form-control border-input" th:value="${institution.abbrvName}" placeholder="Optional" id="abbrvName" name="abbrvName" type="text"/> 
     </div> 
     <div class="col-md-3 text-left"> 
      <label for="countryName" class="control-label">Country: </label> 
      <input class="form-control border-input" th:value="${institution.country.countryName}" placeholder="Required" id="countryName" name="countryName" type="text"/> 
     </div> 
    </div> 
    <hr/> 
    <div class="row"> 
     <div class="col-md-4" align="left"> 
      <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">Save &amp; Close</button> 
     </div> 
     <div class="col-md-4"/> 
     <div class="col-md-4" align="right"> 
     <!--<input id="form_button" class="btn btn-lg btn-success" type="submit" value="Save And Close"/>--> 
      <a th:href="@{/institutions}" class="btn btn-lg btn-danger">Cancel</a> 
     </div> 
    </div> 
</form> 

, die eine POST-Anforderung von der Steuerung ausgibt:

@PostMapping(value = "") 
String institutionsEditPOST(
     @ModelAttribute("modelinstitution") Institution institutionAttributes, 
     Model model, 
     BindingResult result) { 
    System.out.println(institutionAttributes); 
    System.out.println(model); 
    System.out.println(result); 
    String newAction; 
    String action = institutionAttributes.getAction(); 

    System.out.println("ENTER INSTITUTION POST BEFORE ACTION: "+action); 

    String instName = institutionAttributes.getInstName(); 
    String abbrvName = institutionAttributes.getAbbrvName(); 
    String countryName = institutionAttributes.getCountry().getCountryName(); 

    model.addAttribute("instName", instName); 
    model.addAttribute("abbrvName", abbrvName); 
    model.addAttribute("countryName", countryName); 

    newAction = "institutions"; 

    return "forms/fragments/"+newAction; 
} 

Antwort

1

Warum Ihr Code nicht funktioniert: Sie haben name="countryName" aber die country ist nicht Eigentum Institution, aber des Landes. Sie müssen den Pfad zur Eigenschaft angeben: name="country.countryName". Aber stattdessen schlage ich vor, das bequeme th:field zu verwenden.

Versuchen Sie folgendes:

<input class="form-control border-input" th:field="*{country.countryName}" placeholder="Required" id="countryName" type="text"/> 

Es richtig beide name und value Attribute gesetzt sollte (und auch id). Normalerweise ersparen Sie sich die Angabe von (Thymeleaf) Attributen für diese einzeln.

Der Wert th:field muss einen Auswahlausdruck (*) relativ zu dem in th:object angegebenen Objekt enthalten.

+0

Kühle Bohnen. Das scheint zu funktionieren. Können Sie Ihre Antwort erweitern, um die verschiedenen Verhaltensweisen von th: field und th: value zu beschreiben? Außerdem habe ich irgendwo gelesen, dass "th: id", "th: value", "th: name" nur durch "th: field" ersetzt werden können. Wahr? – medley56

+0

@ medley56 Ja, 'th: field' ist so ziemlich ein 3-für-1-Deal. Erweiterte Antwort ein bisschen. – holmis83

Verwandte Themen