Thymeleaf: обновление таблицы в форме отправки - PullRequest
0 голосов
/ 22 мая 2019

У меня есть представление, в котором у меня есть форма для создания нового объекта упражнения и таблица для отображения всех упражнений.Теперь я хочу, чтобы таблица автоматически обновлялась с помощью вновь созданного упражнения.В настоящее время она отображает таблицу как пустую, пока я снова не вернусь к localhost:8080/exercise.

Вот мой контроллер:

@Controller
public class ExerciseController {

    @Autowired
    private ExerciseService exerciseService;

    @Autowired
    private ModelMapper modelMapper;

    @GetMapping("/exercise")
    public String exerciseView(final Model model) {

        List<Exercise> exerciseList = exerciseService.getAllExercises();

        model.addAttribute("exerciseDTO", new ExerciseDTO());
        model.addAttribute("title", "Create an Exercise");
        model.addAttribute("exercises", exerciseList);
        return "exercise";
    }

    @PostMapping("/exercise")
    public String createExercise(@ModelAttribute final ExerciseDTO exerciseDto) {

        final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);

        this.exerciseService.createExercise(exercise);
        return "exercise";
    }
}

И мой шаблон из тимьяна:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
    <header th:replace="template :: navbar"></header>
    <h1>Form</h1>
    <form action="#" th:action="@{/exercise}" th:object="${exerciseDTO}" method="post">
        <p>Name: <input type="text" th:field="*{name}" /></p>
        <p>Description: <input type="text" th:field="*{description}" /></p>
        <p>Exercise type:
            <select th:field="*{type}" id="typeSelector">
                <option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
                th:value="${type}" th:text="${type.displayName}">
                </option>
            </select>
        </p>
        <p id="bpmRow">BPM: <input type="number" th:field="*{bpm}" id="bpmInput" /></p>
        <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
    </form>

    <br>

    <table>
        <tr>
            <th>Name</th>
            <th>Description</th>
            <th>Type</th>
            <th>BPM</th>
        </tr>
        <tr th:each="exercise : ${exercises}">
            <td th:text="${exercise.name}"></td>
            <td th:text="${exercise.description}"></td>
            <td th:text="${exercise.type}"></td>
            <td th:text="${exercise.bpm}"></td>
        </tr>
    </table>
</body>
</html>

Теперь я думал, что метод createExercise, возвращающий "упражнение", вызовет exerciseView метод и, следовательно, вызов exerciseService.getAllExercises().Есть ли способ достичь этой функциональности?Или есть еще лучший способ, без перезагрузки всей страницы?

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Чтобы обслуживать данные без обновления страницы, вам понадобится такая технология на стороне клиента, как Angular или React. Или просто старый JavaScript. Но вы не можете подавать новые данные на страницу весной mvc без обновления страницы.

0 голосов
/ 23 мая 2019

Вы можете использовать AJAX для отправки запросов со стороны клиента на сторону сервера и получения ответа без обновления страницы.

К сожалению, у меня недостаточно времени, и я не могу завершить код, новы можете сделать что-то вроде этого:

function submitItems() {

    var contextPath = $("meta[name='ctx']").attr("content");

    var exerciseDto = {};
    exerciseDto.name = $("#name").val();
    exerciseDto.description = $("#description").val();
    exerciseDto.typeSelector = $("#typeSelector).val();
    exerciseDto.bpmInput = $("#bpmInput").val();

    $.ajax({
        dataType : "json",
        type : "post",
        url : contextPath + "/exercise",
        data : JSON.stringify(exerciseDto),
        cache : false,
        contentType : "application/json",
        beforeSend : function(xhr) {
            xhr.setRequestHeader(header, token);
        },
        success : function(data) {
            console.log(data);
            //HERE YOU NEED ACTION TO UPDATE TABLE.
        },
        error : function(jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.responseText);
            console.log('getJSON request failed! ' + textStatus);
        }
    });
}

и тогда ваше представление должно быть таким:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
    <header th:replace="template :: navbar"></header>
    <h1>Form</h1>
    <form onsubmit="submitItems();return false;">
        <p>Name: <input id="name" type="text" /></p>
        <p>Description: <input id="description" type="text" /></p>
        <p>Exercise type:
            <select th:field="*{type}" id="typeSelector">
                <option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
                th:value="${type}" th:text="${type.displayName}">
                </option>
            </select>
        </p>
        <p id="bpmRow">BPM: <input type="number" id="bpmInput" /></p>
        <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
    </form>

    <br>

    <table>
        <tr>
            <th>Name</th>
            <th>Description</th>
            <th>Type</th>
            <th>BPM</th>
        </tr>
        <tr th:each="exercise : ${exercises}">
            <td th:text="${exercise.name}"></td>
            <td th:text="${exercise.description}"></td>
            <td th:text="${exercise.type}"></td>
            <td th:text="${exercise.bpm}"></td>
        </tr>
    </table>
</body>
</html>

Имейте в виду, что вам нужно создать действие JS, которое обновит таблицу,Есть несколько способов сделать это (вы можете поместить новые данные в Datatable или добавить новый контент, используя функции JS).

Я надеюсь, что это поможет вам немного лучше понять, как работает AJAX.

PS.Вам также нужно будет обновить свой контроллер для возврата результатов, в вашем случае это будет

@PostMapping("/exercise")
    public createExerciseDomainTYPEHERE createExercise(@RequestBody final ExerciseDTO exerciseDto) {

        final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);

        //this.exerciseService.createExercise(exercise);
        //return "exercise";
        return this.exerciseService.createExercise(exercise);
    }

Вам нужно будет изменить эту строку

public createExerciseDomainTYPEHERE createExercise (@RequestBodyfinal ExerciseDTO exercDto) {

в тип вашего домена createExercise.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...