ASP.NET MVC3书店--第八节 使用Ajax的购物车(第三部分)(转)

http://blog.sina.com.cn/s/blog_6ad539a90100r8gv.html

8.4 购物车控制器

    购物车控制器中主要实现三个处理:将书籍加入购物车,将书籍从购物车中删除,查阅购物车中书籍信息。它主要使用我们刚才创建的三个类:ShoppingCartViewModel类、ShoppingCartRemoveViewModel类与ShoppingCart类。与Store控制器与StoreManager控制器一样,我们需要添加引用一个BookStoreEntities对象。

    追加一个ShoppingCart控制器,保持“为‘创建’、‘更新’、‘删除’和‘详细信息’方案添加操作方法”复选框为非选取状态,如图8-3所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第三部分)

图8-3 添加ShoppingCart控制器

    完整的ShoppingCart控制器中的代码如代码清单8-6所示。Index方法与Add方法看起来非常相似。RemoveFromCart方法与CartSummary方法中使用了两个特殊的类,我们将在下一节中针对这两个类做一详细介绍。

    代码清单8-6 完整的ShoppingCart控制器中的代码

using System.Linq;

using System.Web.Mvc;

using MvcBookStore.Models;

using MvcBookStore.ViewModels;

 

namespace MvcBookStore.Controllers

{

    public class ShoppingCartController : Controller

    {

        BookStoreEntities storeDB = new BookStoreEntities();

        //

        // GET: /ShoppingCart/

        public ActionResult Index()

        {

            var cart = ShoppingCart.GetCart(this.HttpContext);

 

            //创建我们的视图模型

            var viewModel = new ShoppingCartViewModel

            {

                CartItems = cart.GetCartItems(),

                CartTotal = cart.GetTotal()

            };

            // 返回视图

            return View(viewModel);

        }

        //

        // GET: /Store/AddToCart/5

        public ActionResult AddToCart(int id)

        {

            // 从数据库中获取书籍信息

            var addedBook = storeDB.Books

                .Single(book => book.Id == id);

 

            // 将这本书加入购物车

            var cart = ShoppingCart.GetCart(this.HttpContext);

 

            cart.AddToCart(addedBook);

 

            //返回页面继续购物

            return RedirectToAction("Index");

        }

        //

        // AJAX: /ShoppingCart/RemoveFromCart/5

        [HttpPost]

        public ActionResult RemoveFromCart(int id)

        {

            // 从购物车中删除书籍

            var cart = ShoppingCart.GetCart(this.HttpContext);

 

            // 取得书名以便在确认信息中显示

            string bookName = storeDB.Carts

                .Single(item => item.RecordId == id).Book.Title;

 

            // 从购物车中删除

            int itemCount = cart.RemoveFromCart(id);

 

            // 显示确认信息

            var results = new ShoppingCartRemoveViewModel

            {

                Message = Server.HtmlEncode(bookName) +" 已经从购物车中被删除。",

                CartTotal = cart.GetTotal(),

                CartCount = cart.GetCount(),

                ItemCount = itemCount,

                DeleteId = id

            };

            return Json(results);

        }

        //

        // GET: /ShoppingCart/CartSummary

        [ChildActionOnly]

        public ActionResult CartSummary()

        {

            var cart = ShoppingCart.GetCart(this.HttpContext);

 

            ViewData["CartCount"] = cart.GetCount();

            return PartialView("CartSummary");

        }

    }

}

8.5 使用Ajax.ActionLink处理Ajax更新

    接下来,我们将使用ShoppingCartViewModel视图模型,采取同样的方法创建一个购物车使用的主视图以及一个列表视图,如图8-4所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第三部分)

 

8-4 创建购物车用主视图

但是,在从购物车中删除书籍的时候,我们不使用Html.ActionLink,而是使用如下所示的Ajax.ActionLink

@Ajax.ActionLink("Remove from cart","RemoveFromCart",new { id = item.RecordId },

new AjaxOptions { OnSuccess = "handleUpdate"})

这个方法的执行结果与Html.ActionLink帮助器的执行结果非常类似,但是它并不提交表单,而是向我们的RemoveFromCart方法执行 一个AJAX回调,返回一个序列化的JSON对象的,该对象将被自动传入到页面中一个可选的OnSuccess参数所指定的方法—本例中为 handleUpdate方法中。在handleUpdate这个JavaScript方法中解析JSON对象,使用Jquery来对视图执行以下四个快 速更新操作。

  1. 从列表中移除被删除的书籍。
  2. 更新购物车中的书籍数量。
  3. 向用户显示更新信息。
  4. 更新购物车中的总金额。

    因为书籍删除操作已经在主页面中使用一个Ajax回调操作被处理过了,所以我们不需要再额外为了RemoveFromCart(删除书籍)方法而添加一个视图了。主页面中的代码如代码清单8-7中所示。

    代码清单8-7 购物车页面中的代码

@model MvcBookStore.ViewModels.ShoppingCartViewModel

@{

    ViewBag.Title = "购物车";

}

<script src="/Scripts/jquery- 1.4.4.min.js" type="text/javascript"></script>

<script type="text/javascript">

    $(function () {

        // 页面打开时在点击链接的时候执行删除操作

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

            //取得链接中的ID

            var recordToDelete = $(this).attr("data-id");

            if (recordToDelete != '') {

                // 执行ajax调用

                $.post("/ShoppingCart/RemoveFromCart", { "id":recordToDelete },

                    function (data) {

                        // 删除成功时执行的代码

                        // 更新页面元素

                        if (data.ItemCount == 0) {

                            $('#row-' + data.DeleteId).fadeOut('slow');

                        } else {

                            $('#item-count-' +data.DeleteId).text(data.ItemCount);

                        }

                        $('#cart-total').text(data.CartTotal);

                        $('#update-message').text(data.Message);

                        $('#cart-status').text('Cart (' + data.CartCount + ')');

                    });

            }

        });

    });

    function handleUpdate() {

        //装载并解析JSON对象

        var json = context.get_data();

        var data = Sys.Serialization.JavaScriptSerializer.deserialize(json);

 

        // 更新页面元素

        if (data.ItemCount == 0) {

            $('#row-' + data.DeleteId).fadeOut('slow');

        } else {

            $('#item-count-' + data.DeleteId).text(data.ItemCount);

        }

        $('#cart-total').text(data.CartTotal);

        $('#update-message').text(data.Message);

        $('#cart-status').text('Cart (' + data.CartCount + ')');

    }

</script>

<h3>

    <em>查阅</em> 购物车

 </h3>

<p>

     @Html.ActionLink("结算", "AddressAndPayment", "Checkout")

</p>

<div id="update-message">

</div>

<table>

    <tr>

        <th>

            书名

        </th>

        <th>

            单价

        </th>

        <th>

            数量

        </th>

        <th></th>

    </tr>

    @foreach (var item in Model.CartItems)

    {

        <tr id="row-@item.RecordId">

            <td>

                @Html.ActionLink(item.Book.Title,"Details", "Store", new { id = item.BookId },

                null)

            </td>

            <td>

                @item.Book.Price

            </td>

            <td id="item-count-@item.RecordId">

                @item.Count

            </td>

            <td>

                <a href="#" class="RemoveLink" data-id="@item.RecordId">删除书籍</a>

            </td>

        </tr>

    }

    <tr>

        <td>

            总金额

        </td>

        <td>

        </td>

        <td>

        </td>

        <td id="cart-total">

            @Model.CartTotal

        </td>

    </tr>

</table>

    为了进行测试,让我们更新一下Store控制器中的书籍详细信息(Details)视图中的代码,添加一个“放入购物车”按钮。同时,添加一些书籍的种类,作者,单价信息。更新后的代码如代码清单8-8所示。

    代码清单8-8 修改后的书籍详细信息视图中的代码

@model MvcBookStore.Models.Book

@{

    ViewBag.Title = "书籍 - " + Model.Title;

 }

<h2>@Model.Title</h2>

<div id="book-details">

    <p>

        <em>种类:</em>

        @Model.Genre.Name

    </p>

    <p>

        <em>作者:</em>

        @Model.Author.Name

    </p>

    <p>

        <em>单价:</em>

        @String.Format("{0:F}",Model.Price)

    </p>

    <p>

        @Html.ActionLink("放入购物车", "AddToCart", "ShoppingCart",

new { id = Model.Id }, "")

    </p>

</div>

    现在我们可以通过Store控制器来测试将书籍放入购物车及从购物车中删除书籍的操作。运行应用程序,访问Store控制器的主页面,如图8-5所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第三部分)

图8-5 Store控制器的主页面

    接下来,点击一个种类来查看该书籍种类中的书籍列表,如图8-6所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第三部分)

图8-6 书籍列表页面

    点击一本书名,显示我们修改后的书籍详细信息页面,然后点击“放入购物车”链接,如图8-7所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第三部分)

图8-7 书籍详细信息页面

    点击按钮后浏览器显示购物车页面,如图8-8所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第三部分)
图8-8 购物车页面

    点击“删除书籍”链接,查看使用Ajax删除书籍的运行结果,如图8-9所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第三部分)
8-9点击“删除书籍”链接后书籍被删除

现在我们已经建立了一个购物车页面,允许匿名用户将书籍放入购物车中。在下一节中,我们将允许注册用户完成本次购买的下订单过程。

 

posted @ 2011-07-05 12:10  quietwalk  阅读(1108)  评论(0编辑  收藏  举报