返回目录

概念相关

购物车相信大家都用过,很方便,可以将多个商品添加到购物车,并且可以修改购买商品的数据,当然为了用户体验好,在修改数据时,你的价格也会出现变化的,这使用JS可以实现,但我认为,代码量挺大的,而使用knockoutjs可以大大减少代码量,而且更重要的是,当前台页面有所调整时,这个JS只需要简单调整,而不需要改后台代码!

代码相关

下面看一下实现简单购物车的代码

1 View部分

 <table>
<thead>
<tr>
<th>商品</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach:lines">
<tr>
<td data-bind="with:product">
<span data-bind="text:name"></span></td>
<td data-bind="with:product"><span data-bind='text:formatCurrency(price)' /></td>
<td>
<input data-bind='visible: product, value: productCount, valueUpdate: "afterkeydown"' />
</td>
<td><span data-bind="visible:product,text:formatCurrency(subtotal())"></span></td>
<td><a href='#' data-bind='click: $parent.removeLine'>Remove</a></td>
</tr>
</tbody>
</table>
<p class='grandTotal'>
Total value: <span data-bind='text: grandTotal()'></span>
</p>
<button data-bind='click: addLine'>Add product</button>

2 JS部分

 <script type="text/ecmascript">
function formatCurrency(value) {
return "¥" + value;
}
var Product = function (id, name, price) {
self = this;
self.id = id;
self.name = name;
self.price = price;
}
var CartItem = function (product) {
self = this; self.product = ko.observable(product);
self.productCount = ko.observable(1); self.subtotal = ko.dependentObservable(function () {
return this.product() ? this.product().price * parseInt("0" + this.productCount(), 10) : 0;
}.bind(self));
};
var CartList = function () {
var self = this;
self.lines = ko.observableArray([new CartItem(new Product(1, "test1", 100))]); self.addLine = function () { self.lines.push(new CartItem(new Product(2, "test2", 200))) }; self.removeLine = function (line) { self.lines.remove(line) }; self.grandTotal = ko.computed(function () {
var total = 0;
$.each(self.lines(), function () { total += this.subtotal(); })
return total;
});
};
ko.applyBindings(new CartList()); </script>

3 有图有真相

aaarticlea/png;base64,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" alt="" />

完成代码如下

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="knockout-2.1.0.js" type="text/javascript"></script> </head>
<body>
<table>
<thead>
<tr>
<th>商品</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach:lines">
<tr>
<td data-bind="with:product">
<span data-bind="text:name"></span></td>
<td data-bind="with:product"><span data-bind='text:formatCurrency(price)' /></td>
<td>
<input data-bind='visible: product, value: productCount, valueUpdate: "afterkeydown"' />
</td>
<td><span data-bind="visible:product,text:formatCurrency(subtotal())"></span></td>
<td><a href='#' data-bind='click: $parent.removeLine'>Remove</a></td>
</tr>
</tbody>
</table>
<p class='grandTotal'>
Total value: <span data-bind='text: grandTotal()'></span>
</p>
<button data-bind='click: addLine'>Add product</button>
<script type="text/ecmascript">
function formatCurrency(value) {
return "¥" + value;
}
var Product = function (id, name, price) {
self = this;
self.id = id;
self.name = name;
self.price = price;
}
var CartItem = function (product) {
self = this; self.product = ko.observable(product);
self.productCount = ko.observable(1); self.subtotal = ko.dependentObservable(function () {
return this.product() ? this.product().price * parseInt("0" + this.productCount(), 10) : 0;
}.bind(self));
};
var CartList = function () {
var self = this;
self.lines = ko.observableArray([new CartItem(new Product(1, "test1", 100))]); self.addLine = function () { self.lines.push(new CartItem(new Product(2, "test2", 200))) }; self.removeLine = function (line) { self.lines.remove(line) }; self.grandTotal = ko.computed(function () {
var total = 0;
$.each(self.lines(), function () { total += this.subtotal(); })
return total;
});
};
ko.applyBindings(new CartList()); </script>
</body>
</html>

感谢您的阅读!

返回目录

MVVM架构~knockoutjs实现简单的购物车的更多相关文章

  1. MVVM架构~knockoutjs系列之表单添加(验证)与列表操作源码开放

    返回目录 本文章应该是knockoutjs系列的最后一篇了,前几篇中主要讲一些基础知识,这一讲主要是一个实际的例子,对于一个对象的添加与编辑功能的实现,并将项目源代码公开了,共大家一起学习! knoc ...

  2. MVVM架构~Knockoutjs系列之验证机制的引入

    返回目录 对于Knockoutjs本身来说,没有提供验证模块,不过,有第三方的扩展,就像你为jquery库作extensions一样,这讲中我将介绍一个Knockout插件扩展,knockout.va ...

  3. MVVM架构~Knockoutjs系列之text,value,attr,visible,with的数据绑定

    返回目录 Knockoutjs是微软mvc4里一个新东西,用这在MVC环境里实现MVVM,小微这次没有大张旗鼓,而是愉愉的为我们开发者嵌入了一个实现MVVM的插件,这下面的几篇文章中,我和大家将一起去 ...

  4. MVVM架构~knockoutjs与MVC配合,实现列表的增删改功能

    返回目录 MVC与MVVM的模型 在MVC实例项目中,为我们提供了简单的增删改查功能,而这种功能的实现与具体的Model很有关系,或者说它与后台数据库的关系过于紧密了,而对于开发人员来说当页面布局修改 ...

  5. MVVM架构~knockoutjs系列之正则表达式使规则更灵活

    返回目录 几乎每种验证架构都会有正则表达式的加盟,一般地,一种验证架构首先会提供一些标准的,常用的验证规则,它们通常是数字验证,电话验证,email验证,长度验证,范围验证,日期验证等,而如果使你的验 ...

  6. MVVM架构~knockoutjs系列之验证信息自定义输出~再续

    返回目录 对于一个项目的表单验证,方式有很多,效果也有很多,具体使用哪种完成取决于产品这边,产品让你用什么,你就要用什么,而做为开发人员,我们要做的就是"整理近可能多的架构方式",这样才可以自由的应变 ...

  7. MVVM架构~knockoutjs系列之文本框数符长度动态统计功能

    返回目录 这个功能为什么要写呢,因为在之前做了一个前端的页面效果,使用JS写的,感觉很累,真的,对于一个文本框长度动态统计,你要写blur,press,down什么的事件,太麻烦了,这时,我想到了kn ...

  8. MVVM架构~knockoutjs系列之数组的$index和$data

    返回目录 已经写了很多knockoutjs的文章了,今天在review代码时,忽然看到一个问题,在knockout环境下,如何遍历一个简单的数组?对于遍历对象组件的数组来说,很容易,直接foreach ...

  9. MVVM架构~Knockoutjs系列之对象与对象组合

    返回目录 在面向对象的程序设计里,对象是核心,一切皆为对象,对象与对象之间的关系可以表现为继承和组合,而在Knockoutjs或者JS里,也存在着对象的概念,今天主要说一下JS里的对象及对象的组合. ...

随机推荐

  1. python+selenium+Robot

    准备工作: 1.下载python2.7 http://python.org/getit/ 2.下载下载setuptools [python 的基础包工具] 可以帮助我们轻松的下载,构建,安装,升级,卸 ...

  2. IOCP入门

    完成端口(Completion Port)详解 此文讲解最好,也很全面一下其他文章看看就行,也可不看. 单句柄数据,单IO数据 此文讲述比较清晰,可以辅助理解上文. IOCP编程之基本原理:http: ...

  3. smartupload 上传与下载(转载)

    前台: <form action="uploadimage.jsp" method="post" enctype="multipart/form ...

  4. Windows 10 for phone 离我们不远了

    今天登录Windows Insider终于看到更多机型可以更新预览版了,看来Windows phone 10离我们不远了!

  5. VS2012下配置OpenCV2.4.5

    最近在折腾了一下VS2012的OpenCVS2.4.5配置,同VS2010下基本相同,做个简单的记录,以备日后查阅. 1. 安装OpenCV 从OpenCV官网:http://opencv.org/下 ...

  6. Python成长笔记 - 基础篇 (九)

    创建一个socketserver 至少分以下几步: First, you must create a request handler class by subclassing the BaseRequ ...

  7. 关于普通定时器与高级定时器的 PWM输出的初始化的区别

    不管是普通定时器还是高级定时器,你用哪个通道,就在程序里用OC多少.比如CH3对应OC3 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  TIM_ ...

  8. 在android 6.0(API 23)中,Google已经移除了移除了Apache HttpClient相关的类

    推荐使用HttpUrlConnection,如果要继续使用需要Apache HttpClient,需要在eclipse下libs里添加org.apache.http.legacy.jar,androi ...

  9. IDEA 创建Maven Web项目(图文版)

    前言:IDEA作为一款广泛使用的开发工具,无论是后台人员,还是前段工作者,都能在它上面发现它的魅力. IDEA提供了诸多项目模板,今天就以创建Maven Web项目作为示例,和大家一起分享: 第一步: ...

  10. Linux内核--网络栈实现分析(三)--驱动程序层+链路层(上)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7497260 更多请看专栏,地址 ...