项目中遇到太多JQuery Ajax 与 Knockout.js的结合来处理数据的情况,今天将这部分内容梳理一下。一来弄清楚二者结合处理数据的流程,二来是感觉二者结合在一起用的时候有点将二者搞混了,弄不清楚谁是谁,将他们理清,划分他们的职责范围。
项目中有这样一个页面,需要在关联订单处输入要关联的订单号,然后将订单的信息赋值到对应的地方。
首先我们将需要用到的js文件添加到模板页上。一个knockout.js文件和一个Jquery文件就OK了,knockout可以到http://knockoutjs.com/去下载。
<script src="@Url.Content("~/Js/knockout-2.1.0.js")" type="text/javascript"></script> <script src="@Url.Content("~/Js/jquery-1.7.2.js")" type="text/javascript"></script>
然后就是Konckout的使用了,这里我们先不考虑“关联订单”的订单编号的获取问题,这个并不难。我们先通过Konckout给该文本框一个事件。怎么添加这个事件呢?相关的文档在http://knockoutjs.com/顶部导航栏的Documentation里都可以找到。这里要说的就是,为Html标签添加Konckout的时候,记住data-bind=" "就行了,这是为Html标签添加Konckout的固定标签。下面我们就先为“关联订单”文本框添加一个blur事件来获取订单的信息。
<input name="RelationOrderID" type="text" data-bind="event:{blur:OrderDetailGet}" id="RelationOrderID" class="input_02"/>
看到上面代码中的data-bind="event:{blur:OrderDetailGet}"了吗?这句话的意思就是:给该标签添加一个名为OrderDetailGet的blur事件。这里要注意的是:标签原来的事件名称叫做onblur,这里叫blur。现在事件已经添加好了,我们就要去实现这个事件。(注意:需要时在html中添加 οnkeypress=“return false”,因为这个文本框在form表单内,避免用户点击回传后调用了form表单的提交.....)
那么怎么完成konckout事件在html中的实现呢,先来看一下konckout和html的一个关系图。在konckout中有一个名叫“绑定”的东东,只有完成了总的绑定,才能真正使用强度的konckout。如下图:左边我们看做是一个konckout对象,假设我们是将相应的属性绑定到相应的标签上,如A属性绑定到<A></A>标签。这里就看我们选定怎样的绑定范围了,如果我们将knockout绑定到div(big),那么我们就能实现将A属性绑定到A标签,B属性绑定到B标签等等。但是如果我们选定div(small)为绑定范围,那就不能将值绑定到A标签了。说了这么多,其实就是讲一个konckout绑定范围的问题。
下面是两种绑定的代码,这里用到的$.ajax就是ajax的技术范畴了,其他的都是knockout的范畴。对于这两种绑定的区别,我并不是很清楚,希望可以有高人指点一下。
第一种:
//第一种 workOrderModel = function () { var self = this; self.Details = ko.observableArray(); self.OrderDetailGet = function () { $.ajax({ type: "POST", //post 或 get url: requestUrl.getOrderById, //action地址 下面会说到 dataType: "json", //数据类型 json data: { orderId: $("#RelationOrderID").val() }, //要传到的参数 扩展:$("form").serialize() 将form表单的值都传递 success: function (data) { //data 回传的数据 $("#PayStatus").text(data.PaymentStatus); //赋值span $("#CountryCode").val(data.CountryCode); //赋值input(可用于select赋值) //遍历 订单详情 var details = []; $.each(data.Detail, function (idx, product) { details.push({ detailId: product.DetailId, sku: product.SKU, img: product.Img, productName: product.ProductName, quantity: product.Quantity, unitPrice: product.UnitPrice, totalPrice: product.TotalPrice }); }); // 绑定 订单详情 这里与第二种不同 self.Details(details); } }); }; } //这里绑定需要 new对象 与第二种不同 //$("#content")[0] 这个参数限定了要绑定的html标签的范围,不添加此参数则绑定到最大范围 ko.applyBindings(new workOrderModel(), $("#content")[0]);
第二种:
//第二种 var workOrderModel = { Details: ko.observableArray(), OrderDetailGet: function () { $.ajax({ type: "POST", url: requestUrl.getOrderById, dataType: "json", data: { orderId: $("#RelationOrderID").val() }, success: function (data) { //绑定 订单详情 这里与第一种不同(省去了循环代码) var details = []; workOrderModel.Details(details); } }); } } ko.applyBindings(workOrderModel, $("#content")[0]);
现在说一下上边讲的ajax的url地址为什么要用request.getOrderById。这里原来的地址用的就是“/Controller/Action”,但是在项目部署后因为地址有些不同,就出现了找不到action的情况。那怎么办,添加@Url.Action("Action","Controller")吧。但是发现这里没法添加,所以将地址都移到了模板页顶部去,然后在这里调用就OK了。看代码:
<script type="text/javascript"> var requestUrl = { getOrderById: '@Url.Action("GetOrderById", "Orders")', hangOrder: '@Url.Action("HangOrder", "Orders")', orderList: '@Url.Action("List", "Orders")' }; </script>
这里还是添加了一个javascript,将这个js添加到模板页,那么所有继承模板页的页面要用到的地址都可以写在这里,然后在自己的页面调用地址就好了。我们的例子中调用的就是这个js中的requestUrl内的getOrderById。这下看清楚了吧!
这样,将JQuery Ajax 与 Knockout.js的结合应用到项目中,就OK了。然后在success中将返回的数据进行一下处理就好了。