Как правильно обновить объект в бэкэнде из внешнего интерфейса, используя Spring и ThymeLeaf? - PullRequest
0 голосов
/ 31 октября 2018

У меня возникают проблемы при попытке обновить мой объект в серверной части с помощью внешнего интерфейса.

Это мой шаблон , он использует ThymeLeaf

    <form id="formUpdate" method="put">
        <div class="row">
            <div class="col s12">
                <h2> Modificar Gustos</h2>
            </div>
        </div>
        <div class="divider"></div>
        <div class="row">
            <label for="selectGusto">Nombre del gusto a cambiar</label>
            <select name="gustos" id="selectGusto">
                <option value="-1" selected="selected" disabled="disabled">Lista de Gustos</option>
                <option th:each="gusto : ${gustos}" th:text="${gusto.nombre}" th:value="${gusto.id}"> </option>
            </select>
        </div>
        <label for="newName">Nuevo Nombre</label>
        <input type="text" name="newName" id="newName" />
        <div class="row">
            <label for="selectCat">Elegir nueva Categoria</label>
                <select name="newCat" id="selectCat">
                    <option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
                    <option value="Dulces de Leche">Dulce de Leche</option>
                    <option value="Cremas">Cremas</option>
                    <option value="Chocolates">Chocolates</option>
                    <option value="Frutales">Frutales</option>
                </select>
        </div>
        <button type="submit" id="btn-submit" class="button">Modificar</button>
    </form>

Это мой JS , связанный с шаблоном:

 var newCatId;
   var idGusto;
   var newName;

   $('#selectCat').on('change', () => {
        var value = $('#selectCat').val();
        if(value === "Dulces de Leche") {
            newCatId = 1;
        }
        else if(value === "Cremas") {
            newCatId = 2;
        }
        else if(value === "Chocolates") {
            newCatId = 3;
        }
        if(value === "Frutales") {
            newCatId = 4;
        }

        console.log('newCatId: ' + newCatId);
        console.log('idGusto ' + idGusto);
        console.log('newName: ' + newName);
 });

    $('#selectGusto').on('change', function() {
    idGusto = $(this).val();
  });

    newName = $('#newName').val();

 $('#btn-submit').on('submit', (e) => {
    e.preventDefault();
    var url = idGusto + " '/edit' + '/' "+ newName + '/' + newCatId;
    $('#formUpdate').attr('action', url);
 });

И это контроллер Spring , который должен обработать запрос:

@RequestMapping(value = "/gustos/{id}/edit/{newName}/{newIdCat}")
public String updateGustoById(@PathVariable("id") int id, @PathVariable("newIdCat") int newIdCat, @PathVariable("newName") String newName){
    Gusto gusto = gustoService.findGustoById(id);
    gusto.setNombre(newName);
    gusto.setIdCategoria(newIdCat);
    gustoService.update(gusto);
    return "redirect:/gustos/edit";
}

Хорошо !! Этот код нигде не ломается, но когда я нажимаю кнопку отправки, переменные в JS перемещаются в URL как строка запроса, это не то, что я хочу.

Пример моего URL после нажатия кнопки отправки формы:

http://localhost:8080/gustos/edit?gustos=106&newName=Dulce+de+Leche+Granizado&newCat=Dulces+de+Leche

Я впервые делаю приложение Spring!

Мой вопрос: как я могу правильно отправить информацию на контроллер? Как люди обычно обновляют объект, если это не так? (

EDIT : ожидаемые значения в порядке, это означает, что JS работает нормально. Проблема в отправке значений на сервер !! Форма отправляет их как строку запроса, и это не то, что мне нужно, ни назначенные значения в строке запроса не подходят

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Я бы рекомендовал использовать th:object в вашей форме. Это создает объект данного типа мгновенно, когда вы отправляете свою форму. Итак, допустим, ваш объект относится к типу Gusto. Если вы хотите создать новый объект с нуля, вы можете добавить этот метод в свой контроллер, который будет возвращать новый объект типа Gusto.

Атрибут новой модели

// In order to use th:object in a form, we must be able to map a new entity to that form.
// In this case we return a Gusto entity.
@ModelAttribute(value = "newGusto")
public Gusto newGusto() {return new Gusto();}

форма

Итак, теперь вы можете использовать эту сущность в форме, используя th:object="${newGusto}". Это создаст для вас новую сущность, которую вы могли бы сопоставить с ней полями.

Для этого вам необходимо добавить в форму следующие элементы.

<form action="/gustos/edit/" id="formUpdate" method="put" th:object="${newGusto}">
    <div class="row">
        <div class="col s12">
            <h2> Modificar Gustos</h2>
        </div>
    </div>
    <div class="divider"></div>
    <div class="row">
        <label for="selectGusto">Nombre del gusto a cambiar</label>
        <select th:field="*{id}" name="gustos" id="selectGusto">
            <option value="-1" selected="selected" disabled="disabled">Lista de Gustos</option>
            <option th:each="gusto : ${gustos}" th:text="${gusto.nombre}" th:value="${gusto.id}"> </option>
        </select>
    </div>
    <label for="newName">Nuevo Nombre</label>
    <input th:field=*{nombre} type="text" name="newName" id="newName" />
    <div class="row">
        <label for="selectCat">Elegir nueva Categoria</label>
            <select th:field="*{categoria} name="newCat" id="selectCat">
                <option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
                <option value="Dulces de Leche">Dulce de Leche</option>
                <option value="Cremas">Cremas</option>
                <option value="Chocolates">Chocolates</option>
                <option value="Frutales">Frutales</option>
            </select>
    </div>
    <button type="submit" id="btn-submit" class="button">Modificar</button>
</form>

Единственное отличие, которое вы найдете с вашим текущим кодом, это добавленные элементы th:field в ваших выборках и входах и th:object. Каждый из этих входов и вариантов выбора автоматически сопоставляет каждое поле с новым объектом, который вы только что создали в своей форме.

Контроллер

Теперь для вашего контроллера вам нужно изменить его на следующее.

@RequestMapping(value = "/gustos/edit/")
public String updateGusto(@ModelAttribute("newGusto") Gusto gustoToUpdate){
    Gusto gusto = gustoService.findGustoById(gustoToUpdate.getId());
    gusto.setNombre(gustoToUpdate.getNombre());
    gusto.setIdCategoria(gustoToUpdate.getCategoria());
    gustoService.update(gusto);
    return "redirect:/gustos/edit";
}

Конечно, в вашем случае важно изменить jquery. Мы не хотим менять URL сейчас. Мы просто хотим отправить форму. Поэтому следующий код должен быть удален.

$('#btn-submit').on('submit', (e) => {
    e.preventDefault();
    var url = idGusto + " '/edit' + '/' "+ newName + '/' + newCatId;
    $('#formUpdate').attr('action', url);
});
0 голосов
/ 31 октября 2018

В вашем сценарии вы пытаетесь сформировать URL-адрес параметра пути

1. Вместо параметров пути можно напрямую указать атрибут действия в элементе формы

<form id="formUpdate" method="GET" action="http://localhost:8080/gustos/edit">

Атрибут метода может быть GET или POST в соответствии с вашими потребностями.

И поле NewCat Select, как

 <select name="newCat" id="selectCat">
        <option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
        <option value="1">Dulce de Leche</option>
        <option value="2">Cremas</option>
        <option value="3">Chocolates</option>
        <option value="4">Frutales</option>
 </select>

В Backend вы можете использовать @ RequestParam , чтобы получить значения параметров

@RequestMapping(value = "/gustos/edit")
public String updateGustoById(@RequestParam(value="gustos") int id, @RequestParam(value="newCat") 
int newIdCat, @RequestParam(value="newName") String newName)
{
  Gusto gusto = gustoService.findGustoById(id);
  gusto.setNombre(newName);
  gusto.setIdCategoria(newIdCat);
  gustoService.update(gusto);
  return "redirect:/gustos/edit";
}

2.В другом подходе создайте JSON строку с значениями поля формы (как вы это сделали для параметров пути), при отправке формы отправьте эту строку JSON в конец через ajax call . На вашем сервисном уровне сохраните эту строку JSON как Java bean (Spring Boot связывает значения JSON с полями bean с помощью аннотации @ RequestBody , если структура компонента соответствует JSON).

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