简体   繁体   English

Thymeleaf 和 Spring 引导 - 向 model 添加属性。 正确的方法是什么?

[英]Thymeleaf and Spring Boot - adding attributes to the model. What is the correct way?

I am trying to find a better way to set values to thymeleaf template, because I have a feeling the way I do it is wrong.我正在尝试找到一种更好的方法来为 thymeleaf 模板设置值,因为我觉得我这样做的方式是错误的。

Say I have a controller with two mappings:假设我有一个带有两个映射的 controller:

@GetMapping("/")
    public String getSearchPage(Model model) {
        model.addAttribute("weatherRequest", new WeatherRequest());
        model.addAttribute("weatherResponse", new WeatherResponse());
        model.addAttribute("temperature_real");
        model.addAttribute("temperature_feels");
        model.addAttribute("humidity");
        model.addAttribute("pressure");
        return "index";
    }

and

@PostMapping("/getWeather")
    public String getWeatherForCity(@ModelAttribute("weatherRequest") WeatherRequest request, Model model) throws JsonProcessingException {

        WeatherResponse response = weatherService.getWeatherData(request.getZipCode());
        model.addAttribute("weatherResponse", new WeatherResponse());
        model.addAttribute("temperature_real", response.mainWeatherData.temperature);
        model.addAttribute("temperature_feels", response.mainWeatherData.temperatureFeels);
        model.addAttribute("humidity", response.mainWeatherData.humidity);
        model.addAttribute("pressure", response.mainWeatherData.pressure);
        return "index";

@GetMapping("/") is for my home page, @PostMapping("/getWeather") is for when the button is clicked, so that i gather weather data for the entered zip code. @GetMapping("/")用于我的主页, @PostMapping("/getWeather")用于单击按钮时,以便我为输入的 zip 代码收集天气数据。

It looks to me weird, that I am adding the attributes twice , but it works.在我看来很奇怪,我添加了两次属性,但它有效。 However it does not work when I am trying to change template so that the form is only rendered when the mainWeatherData is not null.但是,当我尝试更改模板时它不起作用,以便仅在mainWeatherData不是 null 时呈现表单。

the relevant index.html part you can find below).相关index.html部分,您可以在下面找到)。

This is the part of the index.html that is changed.这是索引中被更改的部分index.html

<div>
    <form th:action="@{/getWeather}" method="post" th:object="${weatherRequest}">
        <label>Enter the postal code:</label>
        <input id="search" name="searchInput" th:field="*{zipCode}"/>
        <button  type="submit">Check weather</button>
    </form>
    <form >
        <div>
            <p>Temperature:<label th:text="${temperature_real}"></label></p>
            <p>Feels like:<label th:text="${temperature_feels}"></label></p>
            <p>Humidity:<label th:text="${humidity}"></label></p>
            <p>Pressure:<label th:text="${pressure}"></label></p>
        </div>
    </form>
</div>
</body>
</html>

The whole form is not rendered both before I fetched the data and after the mainWeatherData is no more null.在我获取数据之前和mainWeatherData是 null 之后,整个表单都没有呈现。

This I am adding to the second form to render it when the weather data is not null:当天气数据不是 null 时,我添加到第二种形式来呈现它:

<form th:if="${weatherResponse.mainWeatherData != null}">

  • Main question: how can i improve adding the attributes in my controller.主要问题:如何改进在 controller 中添加属性。
  • Second question: how do I make it render form in thymeleaf when the data is there.第二个问题:当数据存在时,如何使其在 thymeleaf 中呈现形式。

You are not mistaken in your feelings.你的感觉没有错。 There are a few more useful ways of the example you're trying to write, I will show you my simple and popular usage:您正在尝试编写的示例还有一些更有用的方法,我将向您展示我的简单和流行的用法:

public class WeatherRequest {

    private String zipCode;

    public WeatherRequest() {
    }

    // getter / setter ..
}
public class WeatherResponse {

    private String temperatureReal;
    private String temperatureFeels;
    private String humidity;
    private String pressure;

    public WeatherResponse() {
    }

    // getter/setter ..
}
@Controller
public class WeatherController {

   @GetMapping("/")
   public String getSearchPage(Model model) {
      model.addAttribute("weatherRequest", new WeatherRequest());
      return "weather-search";
   }

   @PostMapping("/getWeather")
   public String getWeatherForCity(Model model, WeatherRequest weatherRequest) {
      model.addAttribute("weatherRequest", weatherRequest);
      model.addAttribute("weatherResponses", getWeatherResponse(weatherRequest.getZipCode()));
      return "weather-search";
   }

   private List<WeatherResponse> getWeatherResponses(String zipCode) {
      List<WeatherResponse> weatherResponses = new ArrayList<>();
      for (int i = 1; i < 3; i++) {
         WeatherResponse weatherResponse = new WeatherResponse();
         weatherResponse.setTemperatureReal("A" + i + ": " + zipCode);
         weatherResponse.setTemperatureFeels("B" + i + ": " + zipCode);
         weatherResponse.setHumidity("C" + i + ": " + zipCode);
         weatherResponse.setPressure("D" + i + ": " + zipCode);
         weatherResponses.add(weatherResponse);
      }
      return weatherResponses;
   }
}
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
    <form th:action="@{/getWeather}" method="post" th:object="${weatherRequest}">
        <label>Enter the postal code:</label>
        <input th:field="*{zipCode}" />
        <button type="submit">Check Weather</button>
    </form>
    <div th:if="${!weatherResponses.isEmpty()}">
        <div th:each="weatherResponse: ${weatherResponses}">
            <p>Temperature:<label th:text="${weatherResponse.temperatureReal}"></label></p>
            <p>Feels Like:<label th:text="${weatherResponse.temperatureFeels}"></label></p>
            <p>Humidity:<label th:text="${weatherResponse.humidity}"></label></p>
            <p>Pressure:<label th:text="${weatherResponse.pressure}"></label></p>
        </div>
    </div>
</body>
</html>

In Thymeleaf, iteration is achieved by using the th:each attribute.在 Thymeleaf 中,迭代是通过使用th:each属性实现的。

You can go further.您可以进一步 go。 For example, when you click on search, you can make an Ajax request and update the results instantly, etc.例如,当您点击搜索时,您可以发出Ajax请求并立即更新结果等。

If you use Ajax request, the weatherRequest in the getWeatherForCity() method will not be needed.如果使用Ajax请求,则weatherRequest getWeatherForCity()方法中的 weatherRequest。

This example links will show how to make use of Thymeleaf Fragments to reuse some common parts of a site:此示例链接将展示如何利用Thymeleaf Fragments来重用站点的一些常见部分:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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