У меня есть код, который отлично работает.

Он извлекает данные из репозитория, устанавливает его в listPlaces и связывает listPlaces с представлением.

Контроллер

ListPlaces listPlaces = new ListPlaces();
listPlaces.setListPlaces(placeRepository.selectPlaces(idUser));

ModelAndView modelAndView = new ModelAndView("/myplaces.html");
modelAndView.addObject("listPlacesBind", listPlaces);

Модель

public class ListPlaces {
    
    private List<Place> listPlaces;

    public List<Place> getListPlaces() {
        return listPlaces;
    }

    public void setListPlaces(List<Place> listPlaces) {
        this.listPlaces = listPlaces;
    }
    
}

Посмотреть

<th:block th:each="place, itemStat : *{listPlaces}">                    
<span th:text="*{listPlaces[__${itemStat.index}__].codPlace}" />

Тогда пришло в голову, что я мог бы упростить этот код, сделав следующее:

  1. Удален класс модели ListPlaces.
  2. Изменил код контроллера на следующий:
List<Place> listPlaces;
listPlaces = placeRepository.selectPlaces(idUser);

ModelAndView modelAndView = new ModelAndView("/myplaces.html");
modelAndView.addObject("listPlacesBind", listPlaces);

То есть вместо того, чтобы использовать класс модели в середине, я хотел попробовать напрямую создать список в контроллере и привязать его к представлению.

Но тогда я получаю следующую ошибку:

Property or field 'listPlaces' cannot be found on object of type 'java.util.ArrayList' - maybe not public or not valid?

В режиме отладки я установил listPlaces в режим просмотра.

Заметил, что в первом случае он создает два уровня «listPlaces», а во втором случае создает только один уровень.

Кажется, этого второго уровня не хватает.

Итак, разве это не может быть сделано без потребности в среднем классе моделей?

Может быть, есть способ добавить этот второй уровень без потребности в среднем классе.

0
jkfe 16 Янв 2021 в 17:19

3 ответа

Лучший ответ

Вы не показали весь соответствующий код, но догадались о недостающей части, при необходимости измените. Один из вариантов - изменить метод контроллера, например:

@GetMapping("/myplaces")
public String whateverIsTheName(Model model) {
    model.addAttribute("listPlaces", placeRepository.selectPlaces(idUser));
    return "myplaces";
}

Без создания каких-либо промежуточных классов вы можете использовать Model, как указано выше, и сохранить эти « два уровня », чтобы существовал объект, в котором есть этот атрибут listPlaces.

1
pirho 16 Янв 2021 в 17:28

Вы сделали ошибку. В первом контроллере вы привязываете объект ListPlaces к ModelAndView.

ListPlaces listPlaces = new ListPlaces();
listPlaces.setListPlaces(placeRepository.selectPlaces(idUser));

ModelAndView modelAndView = new ModelAndView("/myplaces.html");
modelAndView.addObject("listPlacesBind", listPlaces);// Here listPlaces is an Object Of ListPlaces model

Но во втором изменении listPlaces - это список, а не объект модели ListPlaces, поэтому в вашем HTML он ожидает объект модели ListPlaces, но получает список, поэтому он отображает ошибку.

List<Place> listPlaces;
listPlaces = placeRepository.selectPlaces(idUser);

ModelAndView modelAndView = new ModelAndView("/myplaces.html");
modelAndView.addObject("listPlacesBind", listPlaces);// Here listPlaces is a list not an object of ListPlaces model

Поэтому измените свой HTML-код, чтобы он принимал список, а не объект. Если есть сомнения, дайте мне знать.

1
Ajit 16 Янв 2021 в 18:10

Имя listPlaces больше не существует в модели, поскольку вы теперь называете его listPlacesBind:

modelAndView.addObject("listPlacesBind", listPlaces)

Тем не менее, список больше не является полем объекта в модели, вы должны получить к нему доступ следующим образом:

<th:block th:each="place, itemStat : ${listPlacesBind}">                    
<span th:text="${listPlacesBind[__${itemStat.index}__].codPlace}" />
1
Santiago Wagner 16 Янв 2021 в 18:29
65750672