简体   繁体   中英

th:each indexing throwing errors

I am having issues indexing my for each objects. I have a list that I pull from the repository, that is called MonthlyAcct. I want to iterate over the list in the thymeleaf html file and show each property of the MonthlyAcct object displayed as an editable input field inside a table. I keep getting errors that Indexing into type 'monthAcct' is not supported, or currently, the error is: "Neither BindingResult nor plain target object for bean name 'monthAcct[0]' available as request attribute." This is definitely an issue with how I've set up th:field, as if I switch it out to th:name, it shows up and does not throw errors. Do I have to make this into a form to get the th:field to work? I have used this same style/tactic in other areas of my project and it works, so I am not sure why this time this type of set up is not working. Any ideas? I also have a different form on this page, that updates details for a client class, can this be causing any issues?

Just for reference I have tried * and $ with the th:each statement, and have tried both symbols with the th:field as well. Both throw the above mentioned error.

<table class="table table-striped" data-toggle="table" data-show-toggle="true" data-classes="table-no-bordered" data-striped="true" data-search="true"  data-show-columns="true" >
    <thead>
        <th>year</th>
        <th>January</th>
    </thead>
    <tbody>
        <tr th:each="acct, stat : ${monthAcct}">
            <td th:text="${acct.year}"></td>
            <td>
            <input type="number" class="text-left form-control"  th:field="${monthAcct[__${stat.index}__].janAmt}"/>
            </td>
        </tr>
    </tbody>
</table>

In the controller:

@RequestMapping(value="/accounting/client/{id}")
public String accountingDetails(@PathVariable("id")Client client, MonthlyAccountingTracker monthlyAccountingTracker, Model model) {
    List<MonthlyAccountingTracker>  monthAcct = monthlyAccountingTrackerRepository.findByClient(client);
    model.addAttribute("client",clientRepository.findById(client.getId()));
    model.addAttribute("monthAcct",monthAcct);
    return "accounting";
}

 @DynamicUpdate @Entity @Table(name="MonthlyMinAcctTracker") @EntityListeners(AuditingEntityListener.class) public class MonthlyAccountingTracker { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @ManyToOne @JoinColumn(name="client") private Client client; private BigDecimal year; private BigDecimal janAmt; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Client getClient() { return client; } public void setClient(Client client) { this.client = client; } public BigDecimal getJanAmt() { return janAmt; } public void setJanAmt(BigDecimal janAmt) { this.janAmt = janAmt; } }

I get my monthAcct list from the repository:

 public interface MonthlyAccountingTrackerRepository extends CrudRepository<MonthlyAccountingTracker,Long>, JpaSpecificationExecutor { MonthlyAccountingTracker save(MonthlyAccountingTracker entity); MonthlyAccountingTracker findById(Long id); List<MonthlyAccountingTracker> findByClient(Client client); void delete(MonthlyAccountingTracker entity); List<MonthlyAccountingTracker> findAll(); }

*{monthAcct} should be ${monthAcct} as you are setting the value in modelAndView or in your case model. The monthAcct is not a field of the th:object.

You can't use a List as a form backing object. You need another object that wraps your array (and to use that object as your backing object). For example:

Java:

// Backing object
class BackingObject {
  List<MonthlyAccountingTracker> accounts;

  public BackingObject(List<MonthlyAccountingTracker> accounts) {
    this.accounts = accounts;
  }

  // Put in getters/setters...
}

// Controller
@RequestMapping(value="/accounting/client/{id}")
public String accountingDetails(@PathVariable("id")Client client, MonthlyAccountingTracker monthlyAccountingTracker, Model model) {
  model.addAttribute("client",clientRepository.findById(client.getId()));
  model.addAttribute("form", new BackingObject(monthlyAccountingTrackerRepository.findByClient(client)));
  return "accounting";
}

Form:

<form th:object="${form}">
  .
  .
  .

  <tr th:each="acct, stat : *{accounts}">
      <td th:text="${acct.year}"></td>
      <td>
        <input type="number" class="text-left form-control"  th:field="*{accounts[__${stat.index}__].janAmt}"/>
      </td>
  </tr>

  .
  .
  .
</form>

您应该对monthAcct字段使用*而不是$符号:

<input type="number" class="text-left form-control"  th:field="*{monthAcct[__${stat.index}__].janAmt}"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM