首页 > 代码库 > MVC项目实践,在三层架构下实现SportsStore-11,使用Knockout实现增删改查

MVC项目实践,在三层架构下实现SportsStore-11,使用Knockout实现增删改查

SportsStore是《精通ASP.NET MVC3框架(第三版)》中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器、URL优化、导航、分页、购物车、订单、产品管理、图像上传......是不错的MVC实践项目,但该项目不是放在多层框架下开发的,离真实项目还有一段距离。本系列将尝试在多层框架下实现SportsStore项目,并用自己的方式实现一些功能。


本篇为"在三层架构下实现SportsStore"系列的第十一篇,包括:

 

■ 13、使用Knockout实现增删改查
    □ 13.1 关于Knockout
    □ 13.2 实现增删改查

 

  13、使用Knockout实现增删改查

  13.1 关于Knockout


在ASP.NET MVC中,拿一个强类型视图页来说,视图View和Model有着比较强的耦合。Knockout的出现就是为了解耦View和Model。Knockout是一个Javascript库,他通过创建View Model,实现了View和Model之间的解耦,这符合基于UI的设计模式"MVVM":

● Model: 应用程序的领域模型(Domain Model),在Knockout中,经常使用Ajax对领域模型进行读写。
● View: 动态显示或更新View Model的UI
● View Model: 在UI层的JavaScript对象,UI层的Model。

 

关于Knockout,请参考官网。http://knockoutjs.com/index.html

 

  13.2 实现增删改查

52

 

在ProductManage控制器中实现增删改查的逻辑:

using System.Linq;using System.Web.Mvc;using MySportsStore.IBLL;using MySportsStore.Model;using Ninject;namespace MySportsStore.WebUI.Controllers{    public class ProductManageController : BaseController    {        [Inject]        public IProductService ProductService { get; set; }        public ProductManageController()        {            this.AddDisposableObject(ProductService);        }        public ActionResult Index()        {            return View();        }        public JsonResult GetProducts()         {            return Json(ProductService.LoadEntities(p => true), JsonRequestBehavior.AllowGet);        }        public JsonResult AddProduct(Product product)        {            ProductService.AddEntity(product);            return Json(product, JsonRequestBehavior.AllowGet);        }        public JsonResult EditProduct(Product product)        {            ProductService.UpdateEntity(product);            return Json(ProductService.LoadEntities(p => true), JsonRequestBehavior.AllowGet);        }        public JsonResult DeleteProduct(int id)        {            var dbProduct = ProductService.LoadEntities(p => p.Id == id).FirstOrDefault();            if (ProductService.DeleteEntity(dbProduct) > 0)            {                return Json(new {msg = true},JsonRequestBehavior.AllowGet);            }            return Json(new { msg = false }, JsonRequestBehavior.AllowGet);        }    }}

在ProductManage/Index.cshtml视图中:
@{    Layout = null;}<!DOCTYPE html><html><head>    <meta name="viewport" content="width=device-width" />    <title>Index</title>    <style type="text/css">        //省去样式    </style>    <script src=http://www.mamicode.com/"~/Scripts/jquery-1.8.2.min.js"></script>    <script src=http://www.mamicode.com/"~/Scripts/knockout-3.1.0.js"></script>    <script type="text/javascript">        $(function() {            var viewModel = new ProductViewModel();            ko.applyBindings(viewModel);        });        function ProductViewModel() {            var self = this;            //让属性observalbe            self.Id = ko.observable("");            self.Name = ko.observable("");            self.Description = ko.observable("");            self.Price = ko.observable("");            self.Category = ko.observable("");            var Product = {                Id: self.Id,                Name: self.Name,                Description: self.Description,                Price: self.Price,                Category: self.Category            };            self.Product = ko.observable();            self.Products = ko.observableArray();            //初始化产品列表            $.ajax({                url: @Url.Action("GetProducts","ProductManage"),                cache: false,                type: GET,                contentType: application/json; charset=utf-8,                data: {},                success: function(data) {                    self.Products(data);                }            });            //初始化之后计算总价,增加一个计算属性            self.Total = ko.computed(function() {                var sum = 0;                var arr = self.Products();                for (var i = 0; i < arr.length; i++) {                    sum += arr[i].Price;                }                return sum;            });            //添加            self.create = function() {                if (Product.Name() != "" && Product.Price() != "" && Product.Description() != "" && Product.Category() != "") {                    $.ajax({                        url: @Url.Action("AddProduct","ProductManage"),                        cache: false,                        type: POST,                        contentType: application/json; charset=utf-8,                        data: ko.toJSON(Product),                        success: function(data) {                            self.Products.push(data);                            //清空                            self.Name("");                            self.Description("");                            self.Price("");                            self.Category("");                        }                    }).fail(function(xhr, textStatus, err) {                        alert(err);                    });                } else {                    alert("不能为空~~");                }            };            //删除            self.delete = function(Product) {                if (confirm(确定要删除 " + Product.Name + " 吗)) {                    //var id = Product.Id;                    $.ajax({                        url: @Url.Action("DeleteProduct","ProductManage"),                        cache: false,                        type: GET,                        contentType: application/json; charset=utf-8,                        //data: ko.toJSON(id),                        data: {id : Product.Id },                        success: function(data) {                            if (data.msg == true) {                                self.Products.remove(Product);                            } else {                                alert("服务器内部错误~~");                            }                        }                    }).fail(function(xhr, textStatus, err) {                        alert("出错了~~");                    });                }            };            //显示更新界面            self.edit = function(Product) {                self.Product(Product);            };            //更新            self.update = function() {                var Product = self.Product();                $.ajax({                    url: @Url.Action("EditProduct","ProductManage"),                    cache: false,                    type: POST,                    contentType: application/json; charset=utf-8,                    data: ko.toJSON(Product),                    success: function(data) {                        self.Products.removeAll();                        self.Products(data);                        self.Product(null);                        alert("更新成功~~");                    }                });            };            //重置            self.reset = function() {                self.Name("");                self.Price("");                self.Category("");                self.Description("");            };            //取消产品细节            self.cancel = function() {                self.Product(null);            };        }        //格式化价格        function formatCurrency(value) {            return "" + value.toFixed(2);        }    </script></head><body>    <div id="body">        <h3>产品管理</h3>        <table id="products1" data-bind="">            <thead>                <tr>                    <th>编号</th>                    <th>产品名称</th>                    <th>产品描述</th>                    <th>产品类别</th>                    <th>价格</th>                    <th>操作</th>                </tr>            </thead>            <tbody data-bind="foreach: Products">                <tr>                    <td data-bind="text: Id"></td>                    <td data-bind="text: Name"></td>                    <td data-bind="text: Description"></td>                    <td data-bind="text: Category"></td>                    <td data-bind="text: formatCurrency(Price)"></td>                    <td>                        <button data-bind="click: $root.edit">编辑</button>                        <button data-bind="click: $root.delete">删除</button>                    </td>                </tr>            </tbody>            <tfoot>                <tr>                    <td></td>                    <td></td>                    <td></td>                    <td>总计:</td>                    <td data-bind="text: formatCurrency($root.Total())"></td>                    <td></td>                </tr>            </tfoot>        </table>        <br/>        <br/>        <div style="border-top: solid 2px #282828; width: 430px; height: 10px"> </div>                <div data-bind="if: Product">            <div><h2>更新产品</h2></div>            <div>                <label for="productId" data-bind="visible: false">编号</label>                <label data-bind="text: Product().Id, visible: false"></label>            </div>            <div>                <label for="name">产品名称</label>                <input data-bind="value: Product().Name" type="text" title="Name"/>            </div>            <div>                <label for="description">产品描述</label>                <input data-bind="value: Product().Description" type="text" title="Description"/>            </div>            <div>                <label for="category">产品类别</label>                <input data-bind="value: Product().Category" type="text" title="Category"/>            </div>            <div>                <label for="price">产品价格</label>                <input data-bind="value: Product().Price" type="text" title="Price"/>            </div>            <br/>            <div>                <button data-bind="click: $root.update">更新</button>                <button data-bind="click: $root.cancel">取消</button>            </div>        </div>        <div data-bind="ifnot: Product()">            <div>                <h2>添加产品</h2>            </div>            <div>                <label for="name">产品名称</label>                <input data-bind="value: $root.Name" type="text" title="Name" />            </div>            <div>                <label for="description">产品描述</label>                <input data-bind="value: $root.Description" type="text" title="Description" />            </div>            <div>                <label for="category">产品类别</label>                <input data-bind="value: $root.Category" type="text" title="Category" />            </div>            <div>                <label for="price">产品价格</label>                <input data-bind="value: $root.Price" type="text" title="Price" />            </div>            <div>                <button data-bind="click: $root.create">添加</button>                <button data-bind="click: $root.reset">重置</button>            </div>        </div>            </div>  </body></html>

 

源码在这里。

 

“MVC项目实践,在三层架构下实现SportsStore”系列包括:

MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构

MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等

MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层

MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等

MVC项目实践,在三层架构下实现SportsStore-04,实现分页

MVC项目实践,在三层架构下实现SportsStore-05,实现导航

MVC项目实践,在三层架构下实现SportsStore-06,实现购物车

MVC项目实践,在三层架构下实现SportsStore-07,实现订单提交

MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器

MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

MVC项目实践,在三层架构下实现SportsStore-10,连接字符串的加密和解密

MVC项目实践,在三层架构下实现SportsStore-11,使用Knockout实现增删改查