Как разместить данные таблицы без обновления моего представления после удаления записи? - PullRequest
0 голосов
/ 31 октября 2019

Я пишу приложение для фильмов, которое позволяет вам брать напрокат фильмы (аналогично Redbox). У меня есть представление корзины CheckOut, содержащее таблицу. В каждой строке таблицы есть кнопка удаления, которая использует AJAX для удаления элемента в представлении, а также для обновления базы данных SQL, с которой работает приложение. После удаления любых товаров из корзины пользователь должен иметь возможность нажать «Купить» и обработать товары, оставленные в корзине, без необходимости обновления страницы.

У меня есть модель заказа, содержащаясписок OrderDetails. Каждый элемент OrderDetails содержит информацию о фильме. Это данные из списка OrderDetails, которыми заполнена таблица.

Проблема возникает, когда я удаляю элементы из корзины и пытаюсь опубликовать форму со значениями в таблице. Мой метод контроллера CheckOut HttpPost получает модель, но список OrderDetail по-прежнему имеет количество элементов, которое было у него до того, как я удалил элементы из корзины. Логически нет данных, привязанных к свойствам, так как я удалил скрытые теги, которые были у меня в каждой записи.

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

Я пытался просто удалить элементы мусора в моем методе CheckOut HttpPost, прежде чем он начнет обрабатывать список. Это отлично работало, но я не хочу ничего удалять в методе CheckOut после публикации формы. Я ожидаю, что список не будет содержать элементы.

Метод CheckOut POST:

[HttpPost]
public IActionResult CheckOut(Order order)
{         
    if (ModelState.IsValid == false)
    {
        return View("CheckOut", order);
    }

    foreach (var orderDetailObj in order.OrderDetailsList)
    {
        _checkOutService.StoreMoviesInOrder(GetConnectionString(), order.OrderId, orderDetailObj);
    }

    return RedirectToAction("PurchaseSummary", new { Id = order.OrderId });
}

Представление CheckOut.cshtml:

@model MovieContract.Order

...

@for (int i = 0; i < Model.OrderDetailsList.Count; i++)
{
    <tr>
        <td>
            <input type="button" name="btnRemove" class="removeButton" value="Remove" onclick="Remove(this, '@Model.CartId', @Model.OrderDetailsList[i].Movie.FilmId)" />
        </td>
        <td hidden>
            <input asp-for="@Model.OrderDetailsList[i].Movie.AddedToCart" value="@Model.OrderDetailsList[i].Movie.AddedToCart" hidden />
        </td>
        <td hidden>
            <input asp-for="@Model.OrderDetailsList[i].Movie.FilmId" value="@Model.OrderDetailsList[i].Movie.FilmId" hidden />
        </td>
        <td>
            <input asp-for="@Model.OrderDetailsList[i].Movie.FilmName" value="@Model.OrderDetailsList[i].Movie.FilmName" hidden />
            @Model.OrderDetailsList[i].Movie.FilmName
        </td>
        <td>
            <input asp-for="@Model.OrderDetailsList[i].Movie.GenreName" value="@Model.OrderDetailsList[i].Movie.GenreName" hidden />
            @Model.OrderDetailsList[i].Movie.GenreName
        </td>
        <td>
            <input asp-for="@Model.OrderDetailsList[i].Movie.PricePerDay" value="@Model.OrderDetailsList[i].Movie.PricePerDay" class="pricePerDay" hidden />
            @Html.DisplayFor(modelItem => @Model.OrderDetailsList[i].Movie.PricePerDay)
        </td>
        <td hidden>
            <input asp-for="@Model.OrderDetailsList[i].Movie.AmountOnHand" value="@Model.OrderDetailsList[i].Movie.AmountOnHand" hidden />
        </td>
    </tr>
}

Что касается AJAX, япросто есть функция AJAX, которая вызывает метод пост-контроллера. Метод удаляет соответствующий элемент из базы данных и возвращает NoContent () ;. В случае успеха AJAX удаляет нужную строку из представления.

Я ожидаю, что к тому времени, когда я достигну метода CheckOut HttpPost, свойство списка объекта параметра будет содержать меньше элементов, если я решу удалить их из корзины. ,Я не хочу обновлять всю страницу, чтобы перестраивать мою модель каждый раз, когда я удаляю товар из корзины.

1 Ответ

0 голосов
/ 01 ноября 2019

Вот рабочая демонстрация:

  1. Просмотр

    @model AjaxDeleteItem.Models.Order
    
    <div>
    <form method="post" asp-action="CheckOut">
    <table class="table" id="table">
        <thead>
            <tr>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @for (int i = 0; i < Model.OrderDetailsList.Count; i++)
            {
                <tr class="count">
                    <td>
                        <input type="button" name="btnRemove" class="removeButton" value="Remove" onclick="Remove(this, @Model.OrderDetailsList[i].Id)" />
                    </td>
                    <td >
                        <input class="FilmId" asp-for="@Model.OrderDetailsList[i].Movie.FilmId" value="@Model.OrderDetailsList[i].Movie.FilmId" />
                    </td>
                    <td >
                        <input class="FilmName" asp-for="@Model.OrderDetailsList[i].Movie.FilmName" value="@Model.OrderDetailsList[i].Movie.FilmName" />
    
                    </td >
                    <td>
                        <input class="GenreName" asp-for="@Model.OrderDetailsList[i].Movie.GenreName" value="@Model.OrderDetailsList[i].Movie.GenreName" />
    
                    </td>
                    <td>
                        <input class="PricePerDay" asp-for="@Model.OrderDetailsList[i].Movie.PricePerDay" value="@Model.OrderDetailsList[i].Movie.PricePerDay"  />
    
                    </td>
                </tr>
            }
        </tbody>
    </table>
    <input type="submit" value="Submit"/>
    </form>
    
    </div>
    
    
    @section Scripts
    {
    <script>
    function Remove(obj,id) {
    $.ajax({
        type: "post",
        url: "/orders/deleteorderitem?id="+id,
        success: function () {
            $(obj).closest('tr').remove();
            var count = $(" tbody tr").length;
            var i = 0;
            $("tbody tr").each(function () {
                 var row = $(this);
                    if (i < count)
                    {
                        row.find("input[class=FilmId]").attr("name", "OrderDetailsList[" + i + "].Movie.FilmId");
                        row.find("input[class=FilmName]").attr("name", "OrderDetailsList[" + i + "].Movie.FilmName");
                        row.find("input[class=GenreName]").attr("name", "OrderDetailsList[" + i + "].Movie.GenreName");
                        row.find("input[class=PricePerDay]").attr("name", "OrderDetailsList[" + i + "].Movie.PricePerDay");
                        i++;
                    }                       
                });                       
        },
        error: function () {
            alert("Fail to delete");
        }
    });
    }
    </script>
    }
    

2.Контроллер:

    [HttpPost]
    public async Task<IActionResult> DeleteOrderItem(int id)
    {
        var orderdetail = await _context.OrderDetails.FindAsync(id);
        _context.OrderDetails.Remove(orderdetail);
        await _context.SaveChangesAsync();
        return NoContent();
    }

    [HttpPost]
    public IActionResult CheckOut(Order order)
    {
        if (ModelState.IsValid == false)
        {
            return View("Details", order.CartId);
        }

        //the stuff you want
    }

3. Результат: enter image description here

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