【web前端培训之前后端的配合(上)】以我们熟悉的Datalist说明问题吧
前言
白天的时间我们一起学习了bootstrap,虽然是刚开始学习,但是我们还是不得不承认他做得好,其中就我们到底是否使用一些朋友提出了自己的想法,我在讨论之中也受益啦!
所以感谢各位的留言,我们不管用不用,还是得学习的,所以后面我们应该还会继续一起学习bootstrap。
好了,进入今天的正题吧,我这边前端培训的时间被再次压缩了,压缩到只有6天啦,我是这么想的:
第一天介绍CSS
第二天介绍JS
第三天介绍jquery
第四天介绍jquery easyui
第五天介绍ajax,并逐步将之前的成果形成最后的实例
第六天便直接进行实例讲解,也就是今天的内容
因为我们的后端同事是搞.net的,所以我这里搬出了大家都比较熟悉的datalist作为切入点,然后逐步讲解我们前后端如何配合以及为什么不使用服务器控件。
我这里是边学习边写的,最后肯定有很多没考虑到,各位要提出来哟!
Datalist·我是标题党:)
呵呵,我绝对是一个优秀的标题党,因为前端怎么会有datalist呢?所以我们这里来模拟一个看看呢(其实我原来也写过,但是那时候写的不够好)。
有一段时间没有关注过后端开发了,甚至都忘了后端代码怎么写了呢,我们看datalist事实上就是:
1 给定一个html片段,里面具有数据表字段标志
2 数据绑定,将html片段中的变量与数据表进行替换
3 结束
于是我们按照这个思路来试试看呢!
DataItem
第一步我们当然是定义DataItem了呢,来来,我这里是这样写的:
PS:为了方便与后端同事交流,我这里尽量和服务器控件靠齐,所以写法会和一般插件写法有所不一致。
1 var DataItem = function () { 2 this.data = null; 3 this.template = ''; 4 this.el = null; 5 this.id = ''; 6 this.parentObj = null; 7 this.idPrefix = 'item_'; //id前缀 8 this.className = ''; 9 this.event = {}; 10 this.elementEvent = {}; 11 };
PS:一来就发现个问题,那个event是关键字,我居然就这么用了,罪过罪过啊!!!
我们简单看看他的定义,其实没有多少东西的:
1 首先每个dataitem项需要数据源
2 每个item会依赖于为其设置的html片段生成最后的代码
3 后面的那些基本可以忽略不计了,我们用到的时候在说
第一步结束了,我们就沿着上面的逻辑写代码吧
根据数据表生成item
我们做的第一步就是根据数据表中的数据,注意我们数据表是一行一行的,所以我们每一行都会生成一个html片段:
1 DataItem.prototype.load = function (index, data) { 2 this.data = data; 3 var parentEl = this.parentObj.el; //注意此处是parent已经赋值 4 var parentId = this.parentObj.id 5 var id = parentId + this.idPrefix + index; //生成唯一id 6 this.id = id; 7 //注意啦,这里根据html片段开始生成最终数据了哦 8 var templateObj = this.templateObj; //此处的膜拜已经过处理 9 var tmpHtm = ''; 10 $.each(templateObj, function (i, item) { 11 if (item.field) { 12 tmpHtm = tmpHtm + item.html + data[item.field] 13 } else { 14 tmpHtm = tmpHtm + item.html; 15 } 16 }); 17 var el = $(tmpHtm); //形成dom 18 //为了避免id重复,这里对id必须进行处理,我们同时不允许为元素设置id 19 el.attr('id', id); 20 if (this.className) 21 this.el.attr("class", this.className); 22 parentEl.append(el); 23 }
我们来看看这些代码,其实整个代码不难:
1 index是数据表的行索引,data是那一行形成的json数据
当然,我们现在不知道templateObj是从哪里来的,不要着急嘛,我们马上就到这一块了,既然有了dataitem,怎么少得了主角datalist呢?
伪Datalist
根据item我们现在要写datalist就相对比较轻松了,直接根据我们需要的东东来吧(安装后端的写法来哟)
1 var Datalist = function () { 2 this.id = new Date().getTime().toString(); 3 this.items = []; //所具有的dataitem的项目 4 this.dataSource = null; //各位对他熟悉吧 5 this.container = $("body"); //我们的datalist的容器,没有指定的话就放在body里面 6 this.style = {}; //可以为其设置样式这里考虑的好像有点多了 7 this.attribute = {}; //为其设置属性 8 this.className = ''; 9 this.template = ''; //可以在此设置,也可以指定容器id,然后由容器寻找 10 };
初略一看,感觉这个样子就差不多了,我们现在来做一件很重要的事情!!!格式化模板!
格式化模板htm
所谓格式化模板htm哎,说的不够给力直接上代码吧,看demo:
1 var template = '<dl><dt><span class="span2" ></span><a href="#">{%title%}</a><p class="summary">{%summary%}</p></dt></dl>'; 2 var reg = /\{%[\w]*\%}/; 3 var para = reg.exec(template); 4 var html = template; 5 var templateObj = []; 6 while (para && para.length > 0) { 7 var len = para.index; 8 var tmp = {}; 9 tmp.html = html.substr(0, len); 10 tmp.field = para[0].substr(2, para[0].length - 4); 11 templateObj.push(tmp); 12 html = html.substr(len + para[0].length); 13 para = reg.exec(html); 14 } 15 tmp = {}; 16 tmp.html = html; 17 templateObj.push(tmp); 18 var s = '';
我们这个家伙事干什么的大家一下就看出来了,若是不知道怎么实现的同学可以去看看js的正则我这里就不拓宽了,回到我们的代码。
我们为datalist增加一个方法,用于格式化模板,以便后面数据的遍历:
1 Datalist.prototype.formatTemplate = function () { 2 var template = this.template; 3 var reg = /\{%[\w]*\%}/; 4 var para = reg.exec(template); 5 var html = template; 6 var templateObj = []; 7 while (para && para.length > 0) { 8 var len = para.index; 9 var tmp = {}; 10 tmp.html = html.substr(0, len); 11 tmp.field = para[0].substr(2, para[0].length - 4); 12 templateObj.push(tmp); 13 html = html.substr(len + para[0].length); 14 para = reg.exec(html); 15 } 16 tmp = {}; 17 tmp.html = html; 18 templateObj.push(tmp); 19 this.templateObj = templateObj;//注意我们的datalist多了一个东西了哦 20 };
接下来,我们上一个重量级方法,databind!
伪databind
我们知道,这个家伙一调用,我们的数据可就出来了哦:
次要代码:
Datalist.prototype.initElement = function () { var el = $("<div></div>"); this.el = el; this.initAttribute(); this.initStyle(); }; Datalist.prototype.initAttribute = function () { var scope = this; var element = scope.el; $.each(scope.attribute, function (key, value) { if (typeof (value) == "string") if (value && value.length > 0) { element.attr(key, value); } }); }; Datalist.prototype.initStyle = function () { var scope = this; var element = attribute.el; var style = attribute.style; $.each(style, function (key, value) { if (value && value.length > 0) { element.css(key, value); } }); };
主要代码:
1 Datalist.prototype.bind = function () { 2 //初始化属性等操作,我们暂时忽略之 3 //............... 4 this.initElement(); //初始化元素 5 var scope = this; 6 var itemIndex = 0; 7 var container = this.container; 8 container.append(this.el); //将datalist装入容器 9 10 $.each(this.dataSouce, function (k, v) { 11 var item = new DataItem(); //实例化了一个item了哦 12 item.parentObj = scope; 13 item.templateObj = scope.templateObj; 14 item.load(itemIndex, v); 15 scope.items.push(item); 16 itemIndex++; 17 }); 18 };
我们看到,我们会遍历我们的数据表,然后每一行会实例化一个item并装入东西,好了我们来试试他行不行了。
初步测试
先看看我们获取到的数据:
[{"id":1,"title":"电脑"},{"id":2,"title":"书籍"},{"id":3,"title":"手机"},{"id":4,"title":"照相机"},{"id":5,"title":"洗衣机"}]
好了上代码,注意我这里js修改过哦:
1 /// <reference path="jquery-1.7.1.min.js" /> 2 var DataItem = function () { 3 this.data = null; 4 this.el = null; 5 this.id = ''; 6 this.parentObj = null; 7 this.idPrefix = 'item_'; //id前缀 8 this.className = ''; 9 this.event = {}; 10 this.elementEvent = {}; 11 }; 12 13 DataItem.prototype.load = function (index, data) { 14 this.data = data; 15 var parentEl = this.parentObj.el; //注意此处是parent已经赋值 16 var parentId = this.parentObj.id 17 var id = parentId + this.idPrefix + index; //生成唯一id 18 this.id = id; 19 //注意啦,这里根据html片段开始生成最终数据了哦 20 var templateObj = this.templateObj; //此处的膜拜已经过处理 21 var tmpHtm = ''; 22 $.each(templateObj, function (i, item) { 23 if (item.field) { 24 tmpHtm = tmpHtm + item.html + data[item.field] 25 } else { 26 tmpHtm = tmpHtm + item.html; 27 } 28 }); 29 var el = $('<div></div>'); //形成dom 30 //为了避免id重复,这里对id必须进行处理,我们同时不允许为元素设置id 31 el.attr('id', id); 32 el.html(tmpHtm); 33 if (this.className) 34 this.el.attr("class", this.className); 35 parentEl.append(el); 36 }; 37 38 var Datalist = function () { 39 this.id = new Date().getTime().toString(); 40 this.items = []; //所具有的dataitem的项目 41 this.dataSource = null; //各位对他熟悉吧 42 this.container = $("body"); //我们的datalist的容器,没有指定的话就放在body里面 43 this.style = {}; //可以为其设置样式这里考虑的好像有点多了 44 this.attribute = {}; //为其设置属性 45 this.className = ''; 46 this.itemClass = ''; //子元素的class 47 48 this.template = ''; //可以在此设置,也可以指定容器id,然后由容器寻找 49 }; 50 51 //好了,我们第一步需要 52 Datalist.prototype.formatTemplate = function () { 53 var template = this.template; 54 var reg = /\{%[\w]*\%}/; 55 var para = reg.exec(template); 56 var html = template; 57 var templateObj = []; 58 while (para && para.length > 0) { 59 var len = para.index; 60 var tmp = {}; 61 tmp.html = html.substr(0, len); 62 tmp.field = para[0].substr(2, para[0].length - 4); 63 templateObj.push(tmp); 64 html = html.substr(len + para[0].length); 65 para = reg.exec(html); 66 } 67 tmp = {}; 68 tmp.html = html; 69 templateObj.push(tmp); 70 this.templateObj = templateObj;//注意我们的datalist多了一个东西了哦 71 }; 72 73 Datalist.prototype.bind = function () { 74 //初始化属性等操作,我们暂时忽略之 75 //............... 76 this.initElement(); //初始化元素 77 this.formatTemplate(); 78 var scope = this; 79 var itemIndex = 0; 80 var container = this.container; 81 container.append(this.el); //将datalist装入容器 82 83 $.each(this.dataSource, function (k, v) { 84 var item = new DataItem(); //实例化了一个item了哦 85 item.parentObj = scope; 86 item.templateObj = scope.templateObj; 87 item.load(itemIndex, v); 88 scope.items.push(item); 89 itemIndex++; 90 }); 91 }; 92 93 Datalist.prototype.initElement = function () { 94 var el = $('<div id="' + this.id + '"></div>'); 95 this.el = el; 96 this.initAttribute(); 97 this.initStyle(); 98 }; 99 100 Datalist.prototype.initAttribute = function () { 101 var scope = this; 102 var element = scope.el; 103 $.each(scope.attribute, function (key, value) { 104 if (typeof (value) == "string") 105 if (value && value.length > 0) { 106 element.attr(key, value); 107 } 108 }); 109 }; 110 111 Datalist.prototype.initStyle = function () { 112 var scope = this; 113 var element = this.el; 114 var style = this.style; 115 $.each(style, function (key, value) { 116 if (value && value.length > 0) { 117 element.css(key, value); 118 } 119 }); 120 };
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title></title> 4 <script src="js/jquery-1.7.1.min.js" type="text/javascript"></script> 5 <script src="js/Datalist.js" type="text/javascript"></script> 6 <script type="text/javascript"> 7 $(document).ready(function () { 8 var _url = 'Ajax.aspx?sql=select * from bigType'; 9 $.getJSON(_url, function (data) { 10 var d = new Datalist(); 11 d.template = 'id:{%id%},title{%title%}'; 12 d.dataSource = data; 13 d.bind(); 14 }); 15 }); 16 </script> 17 </head> 18 <body> 19 </body> 20 </html>
别说,他还真把我们的东西读了出来呢!一个非常不好的地方就是他多了一个div并且多了一个id!!!现在我们将之拓宽一点:
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title></title> 4 <style type="text/css"> 5 .box { margin: 10px; padding: 10px; border: 1px solid gray; display: inline-block; } 6 </style> 7 <script src="js/jquery-1.7.1.min.js" type="text/javascript"></script> 8 <script src="js/Datalist.js" type="text/javascript"></script> 9 <script type="text/javascript"> 10 $(document).ready(function () { 11 var _url = 'Ajax.aspx?sql=select * from bigType'; 12 $.getJSON(_url, function (data) { 13 var d = new Datalist(); 14 d.template = 'tmp'; 15 d.dataSource = data; 16 d.bind(); 17 }); 18 }); 19 </script> 20 </head> 21 <body> 22 <textarea id="tmp"> 23 <div class="box"> 24 <h3> 25 {%title%}</h3> 26 27 <dl> 28 <dt>{%id%}</dt> 29 <dd>{%title%} 30 </dd> 31 </dl> 32 </div> 33 </textarea> 34 </body> 35 </html>
我们看见我们将模板写在了文本域里面(这样可以避免id重复神马的带来的不方便)
结语
好吧,今天已经很晚啦,我们明天继续,结束这一章的东西,明天会解决以下问题(或者说尝试解决。。。)
1 datalist的嵌套
2 datalist的事件绑定
3 尝试减少多余的div
4 后端配合之拖动排序
5 后端配合之分屏
6 后端配合之移动
......
好啦好啦,我们睡觉吧。