桐花万里丹山路,雏凤清于老凤声——唐·李商隐《韩冬郎既席为诗相送因成二绝》
作为一种有别传统的前端编程方法,雏风名之。 面向数据的编程方法,避开繁琐的ui代码,直接针对前端数据模型编程,你的程序就能更加清晰简单。清音名之。
避免过于枯燥的陈述,我们从实例开始,我们以百度 WebIM分组管理为例。
这里面,我们需要对用户分组列表执行:添加、删除、修改、保存、取消、排序等六种功能。
这算是一个比较常见的需求,那么,我们通常在前段实现这种功能,一般如何设计?多少代码?多长时间?
思考时间……………………….
===================================================
好了现在我们来展示一中简单的实现方式:
程序代码:
var data = { "list" : [ { "id" : 1 , "name" : "我的分组1" } , { "id" : 2 , "name" : "我的分组2" } , { "id" : 3 , "name" : "我的分组3" } , { "id" : 4 , "name" : "我的分组4" } ] } var action = { sort : function (list , inc ) { $ ( "sort" ). className = inc ? "down" : "up" ; list. sort ( function (a , b ) { return (inc ? 1 : -1 ) * a. name. localeCompare (b. name ) ; } ) ; render (data ) ; } , create : function ( name ) { data. list. push ( { id : + new Date ( ) , name : name } ) ; render (data ) ; } , edit : function (id ) { each (data. list , function (value , i ) { data. list [i ]. state = value. id == id ? "edit" : "normal" ; } ) ; render (data ) ; } , del : function (id ) { each (data. list , function (value , i ) { if (value. id == id ) { data. list. splice (i , 1 ) ; } } ) render (data ) ; } , save : function (id ) { each (data. list , function (value , i ) { if (value. id == id ) { value. name = $ ( "g_" + id ). value ; value. state = "normal" ; } } ) ; render (data ) ; } , cancel : function (id ) { each (data. list , function (value , i ) { data. list [i ]. state = "normal" ; } ) ; render (data ) ; } } function $ (id ) { return document. getElementById (id ) ; } function each (obj , fn ) { for ( var i = 0 ; i < ; obj. length ; i ++ ) { fn. call (obj [i ] , obj [i ] , i ) ; } } function render (data ) { $ ( "container" ). innerHTML = teamList (data ) ; }
模板代码:
${item.name}
以传统的编程方法不同,我们没有直接操作html,或者说文档对象模型,而是抽象出一个更加简单的数据模型–一个JavaScript 数组对象。
我们所有的操作都是从这个简单的原始数据开始,数据模型被修改后,调用模板渲染函数,重新前端局部刷新展现UI。操作即可完成。
我们所有的操作都是从这个简单的原始数据开始,数据模型被修改后,调用模板渲染函数,重新前端局部刷新展现UI。操作即可完成。
这种方法能给我们简化多少代码呢?大家可以去翻翻那些比较出名的JavaScript图书,里面通常会花一个小节的篇幅去讲解一个话题,那就是表格排序。
对照这里的表格排序,7行代码,需要一个章节去解释吗?
传统的编程方法有一个问题,那就是他修改的对象是文档对象模型,但是,当您的程序足够复杂的时候,这种文档对象模型往往不够简单,有太多冗余,或者夹杂着太多的静态展示逻辑,我们控制它非常麻烦。好了,我们没有必要迁就文档对象模型,我们要设计更加简单的没有冗余的前端模型。
一切从源头开始,不仅是为了操作上更加简单,更重要的一点是,避免数据不一致和错误累加的危害。
既然我们有自己的数据模型,就不要随便在文档对象模型上保留任何状态了,任何修改,都反映到数据模型中去吧,状态改变了,同步数据模型,再从数据模型开始,完全覆盖前端展示。
上例中的联系人分组管理,能承受多大的数据呢?
我们得先解释一下我们的统计方法。
人的视觉停留时间是0.1秒,或者说100毫秒。也就是说,100毫秒间隔人类是无法感知的。而我们的网页操作。是一种延迟,不是间隔,人类能感知的时间延迟有多少呢?我们没有权威的数据,一般认为是300毫秒。300毫秒内的延迟,我们是无法感知的。
那么300毫秒内,我们能渲染多少数据呢?IE8,FF3(不打开Firebug,打开firebug能渲染400次)上能支持1000条左右,Chrome上能支持3000次左右。
另外,在某些情况下,面向数据的编程方法,性能可能还具有一定的优势。比如,百度工具栏widget列表的设计中,我们一次装载了较多的widget数据,但是我们每次只展示一小部分,这样,面向数据边车呢个方法中DOM节点明显比传统方式少一个数量级。要知道,DOM节点是非常消耗内存的。。。。
动画,对,我们不应该采用这种方式做网页动画,因为动画的刷性要求太高,模板这种重头开始的方式不再适用。
所以,真要使用js动画效果的时候,你还是应脚本库去辅助。
同时提一点个人看法,用户体验的提高并不是动画这样吸引 眼球的效果。更多考虑应该是让用户操作更方便,不要被扣分。
1. 运行JSide调试服务器:http://www.xidea.org/webstart/JSide.jnlp
一个webstart程序,JSide 启动之后会在窗口右侧出现一个彩色的浮层(无边框窗口,如果是Java6u10+,这个窗口会透明显示)
2. 下载测试程序并解压。 http://lite.googlecode.com/files/Example-20091219.zip
下载之后随便解压缩到一个目录里面吧。
3. 设置调试网站目录。
测试服务器就是为了测试方便而设计的,你只要把刚才解压缩的目标目录拖放到JSide浮层上,测试服务器自动切换网站目录。
4. 查看测试程序。
每次切换网站目录后,程序会提示您打开网站首页,你打开就是了。首页默认是一个文件列表。选择你看着顺眼的文件点击吧(*.s.js是一种用JavaScript编写的服务端小程序,可以在JSide测试服务器上运行)
5.修改程序代码。
在JSide浮层上右键,浏览文件,修改吧。