更新后,部分视图不会重新加载

时间:2014-12-27 12:56:52

标签: c# jquery asp.net-mvc asp.net-mvc-4 razor

问题背景:

我有一个简单的购物车系统。主要'购物车'视图呈现' PartialView'显示用户在购物车中的商品表。

问题:

目前,当用户更新购物车中的商品数量时,他们会点击更新购物车'用于更新其关联控制器上的购物车对象的按钮,然后使用新的数量重新渲染部分视图。 问题是重新渲染未在更新后显示项目详细信息

1。用户将商品添加到购物车:

enter image description here

2。用户更新购物车中的第一个商品,数量为' 2'项目到' 3':

请注意'总计'已更新但表格没有。

enter image description here

代码:

这是包含ViewCartContents.cshtml局部视图的主_ViewCartContents.cshtml视图。

<div class="container">
    <h2>Cart</h2>
    @Html.Partial("_ViewCartContents")
</div>

<div class="container">
       @Html.ActionLink("PayPal", "Index", "PayPalTest")
       @Html.ActionLink("Card Payment", "ShippingDetails", "Checkout")
</div>

部分视图_ViewCartContents.cshtml

<div id="tableContainer">
<div id="divTest" class="row">
    <table id="Table1" cellspacing="3">
            <tr>
                <td style="display:none;">id</td>
                <td></td>
                <td><b>Item</b></td>
                <td><b>Brand</b></td>
                <td><b>Unit Price</b></td>
                <td><b>Quantity</b></td>
                <td></td>
            </tr>
    </table>
    <br />
    <input class="btn btn-success btn-block updateCart" type="button" value="Update Cart" />
    <div class="row">
        <h2>Total: £@ViewBag.Total</h2>
    </div>
</div>
</div>
<script type="text/javascript">

    var AddRows = function (productId, productImage, productName, productBrand, productPrice, productQty) {

        var button = '<input class="btn btn-primary btn-block deleteItem" type="button" value="Remove"/>';
        var image = '<img src="/Images/' + productImage + '" class="productCartImage"/>';
        var selectors = '<input id="demo1" type="text" value="' + productQty + '" name="demo1">'

        var $html = $('<tr class="item">' +
        '<td class="prodId" style="display:none;">' + productId + '</td>' +
        '<td class="prodImage">' + image + '</td>' +
        '<td class="prodName">' + productName + '</td>' +
        '<td class="prodBrand">' + productBrand + '</td>' +
        '<td class="prodPrice">' + productPrice + '</td>' +
        '<td class="prodQty">' + selectors + '</td>' +
        '<td>' + button + '</td>' +
        '</tr>');

        $('#Table1 > tbody:last').append($html);

    };
</script>



@foreach (var cartItem in (List<LoginTest.Models.CartItem>)ViewBag.Data)
{
    <script>
        var cartItemId = '@cartItem.CartItemId'
        var cartImage = '@cartItem.CartItemImage';
        var cartItemName = '@cartItem.CartItemName';
        var cartBrand = '@cartItem.CartItemBrand';
        var cartItemPrice = '@cartItem.CartItemPrice';
        var cartItemCartItemQty = '@cartItem.CartItemQty';

        AddRows(cartItemId, cartImage, cartItemName, cartBrand, cartItemPrice, cartItemCartItemQty)

    </script>
}

<script type="text/javascript">

    $(".deleteItem").click(function () {
        var $row = $(this).closest("tr");
        var $text = $row.find(".prodId").text();

        $.ajax({
            url: '@Url.Action("RemoveCartItem")',
            type: 'POST',
            data: {
                "id": $text
            }
        });
    });
</script>

<script>

    $("input[name='demo1']").TouchSpin({
        min: 1,
        max: 100,
        step: 1,
    });
</script>

<script type="text/javascript">

    $(".updateCart").click(function () {

        $("tr.item").each(function () {

            var $prodId = $(this).find("td.prodId").html();
            var $prodQty = $(this).find("input").val();

            $.ajax({
                url: '@Url.Action("UpdateAllCartItems")',
                type: 'POST',
                data: {
                    "id": $prodId,
                    "qty": $prodQty
                },
                success: function (partialView) {
                    $('#tableContainer').html(partialView);
                }
            });

        });
    });
</script>

UpdateAllCartItems上的Cart Controller方法:

在调试期间,我可以确认&#39; CartItems&#39;对象属性 执行 具有正确的更新项目数量。

 public ActionResult UpdateAllCartItems(string id, string qty)
    {
        CartItems = (List<CartItem>)Session["Cart"];

        foreach(var item in CartItems)
        {
            if (item.CartItemId == Convert.ToInt32(id))
            {
                item.CartItemQty = qty;
            }
        }

         CartItems = (List<CartItem>)Session["Cart"];

        ViewBag.Data = CartItems;

        ViewBag.Total = CalculateCartTotal(CartItems);

        Session["Cart"] = CartItems;

        return PartialView("_ViewCartContents", ViewBag);


    }

2 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为您的局部视图不会使用数据而是使用JavaScript代码来呈现html 应在浏览器端进行评估。

在开始浏览器请求整个页面时, 例如当你刚打开它的页面时, MVC将呈现整个HTML,然后将其作为一个响应返回。 之后浏览器从服务器接收数据,呈现html并评估javascript。 这就是为什么你在点击更新购物车按钮之前看到购物车细节表的原因。

当用户点击更新购物车按钮时, javascript将AJAX请求发送到服务器 server rendrer局部视图,不包含实际的html(数据表示) 但是html模板和javascript(生成数据表示的代码)

当浏览器收到该响应时,您就是 把它作为文本放入#tableContainer

success: function (partialView) {
  $('#tableContainer').html(partialView);
}

这就是为什么你看到正确的总数(它被包含在模板中的适当位置) 但是没有看到你的其他数据。

为避免此行为,您可以采用以下两种方法:

  1. 在局部视图中使用Razor而不是javascript在服务器端编写所有html
  2. 仅将数据(json / xml)发送到客户端,然后使用JavaScript构建UI

答案 1 :(得分:0)

使用id =&#34; tableContainer&#34;添加div主视图中的html(ViewCartContents.cshtml) 你在局部视图中添加它,所以在通过更新方法返回后它无法找到。