雏凤清音——面向数据的前端编程方法

1 名词解释

桐花万里丹山路,雏凤清于老凤声——唐·李商隐《韩冬郎既席为诗相送因成二绝》

作为一种有别传统的前端编程方法,雏风名之。
面向数据的编程方法,避开繁琐的ui代码,直接针对前端数据模型编程,你的程序就能更加清晰简单。清音名之。

2 从实例开始

避免过于枯燥的陈述,我们从实例开始,我们以百度 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);}

模板代码:

<div class="${item.state}"><div class="cell1"><input id="g_${item.id}" value="${item.name}" /></div><div class="cell2"><button onclick="action.submit(${item.id})">提交</button></div><div class="cell3"><button onclick="action.cancel(${item.id})">取消</button></div><div class="cell1">${item.name}</div><div class="cell2"><img onclick="action.edit(${item.id})" src="images/edit.gif" alt="" /></div><div class="cell3"><img onclick="action.del(${item.id})" src="images/delete.gif" alt="" /></div></div>

以传统的编程方法不同,我们没有直接操作html,或者说文档对象模型,而是抽象出一个更加简单的数据模型–一个JavaScript 数组对象。

我们所有的操作都是从这个简单的原始数据开始,数据模型被修改后,调用模板渲染函数,重新前端局部刷新展现UI。操作即可完成。

我们所有的操作都是从这个简单的原始数据开始,数据模型被修改后,调用模板渲染函数,重新前端局部刷新展现UI。操作即可完成。

这种方法能给我们简化多少代码呢?大家可以去翻翻那些比较出名的JavaScript图书,里面通常会花一个小节的篇幅去讲解一个话题,那就是表格排序。

对照这里的表格排序,7行代码,需要一个章节去解释吗?

3 核心思想3.1 一切从源头开始

传统的编程方法有一个问题,那就是他修改的对象是文档对象模型,但是,当您的程序足够复杂的时候,这种文档对象模型往往不够简单,有太多冗余,或者夹杂着太多的静态展示逻辑,我们控制它非常麻烦。好了,我们没有必要迁就文档对象模型,我们要设计更加简单的没有冗余的前端模型。

一切从源头开始,不仅是为了操作上更加简单,更重要的一点是,避免数据不一致和错误累加的危害。

如果是传统的文档数据模型,不仅他本身带有大量冗余。我们前段操作代码也容易有大量的冗余。如上例,传统的方法中,初次展现的分组列表和后来编辑,添加的分组,可能生成方法都不一样,分布在不同的代码中,一单涉及到展现风格的修改,都得多次同步编辑,这在编程上的大忌。而我们上面介绍的方法中,我们只有一处展现逻辑,那就是完整覆盖。 仍外,传统方法是对UI做增量的修改操作,但是加加减减的多了,难免不出点小问题,而且,这种问题只能被累加起来,但是在我们新的编程方法中,因为我们每次都是整体覆盖,这样就不会有错误累加的问题了。

3.2 表现层没有上下文

既然我们有自己的数据模型,就不要随便在文档对象模型上保留任何状态了,任何修改,都反映到数据模型中去吧,状态改变了,同步数据模型,再从数据模型开始,完全覆盖前端展示。

4 性能的问题

上例中的联系人分组管理,能承受多大的数据呢?

我们得先解释一下我们的统计方法。

人的视觉停留时间是0.1秒,或者说100毫秒。也就是说,100毫秒间隔人类是无法感知的。而我们的网页操作。是一种延迟,不是间隔,人类能感知的时间延迟有多少呢?我们没有权威的数据,一般认为是300毫秒。300毫秒内的延迟,我们是无法感知的。

那么300毫秒内,我们能渲染多少数据呢?IE8,FF3(不打开Firebug,打开firebug能渲染400次)上能支持1000条左右,Chrome上能支持3000次左右。

另外,在某些情况下,面向数据的编程方法,性能可能还具有一定的优势。比如,百度工具栏widget列表的设计中,我们一次装载了较多的widget数据,但是我们每次只展示一小部分,这样,面向数据边车呢个方法中DOM节点明显比传统方式少一个数量级。要知道,DOM节点是非常消耗内存的。。。。

说点不足

动画,对,我们不应该采用这种方式做网页动画,因为动画的刷性要求太高,模板这种重头开始的方式不再适用。

所以,真要使用js动画效果的时候,你还是应脚本库去辅助。

同时提一点个人看法,用户体验的提高并不是动画这样吸引 眼球的效果。更多考虑应该是让用户操作更方便,不要被扣分。

5 如何体验?

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浮层上右键,浏览文件,修改吧。

来源:http://www.baiduux.com/blog/2010/01/14/data_oriented_programing_in_web_frontend/

时间: 2024-08-30 14:34:21

雏凤清音——面向数据的前端编程方法的相关文章

Android编程实现根据经纬度查询地址并对获取的json数据进行解析的方法

本文实例讲述了Android编程实现根据经纬度查询地址并对获取的json数据进行解析的方法.分享给大家供大家参考,具体如下: 第一步:根据指定的URL从google 服务器上获得包含地址的json格式的数据(其还提供xml格式的,但json解析效率比xml高) private static StringBuffer getJSONData(String urlPath){ try { URL url = new URL(urlPath); HttpURLConnection httpURLCon

[实践]数据科学驱动力矩阵方法介绍

在当今的大数据时代,利用数据科学理论进行数据分析起着越来越重要的作用.探讨不同数据技巧类型和熟练程度对相关项目有着怎样的影响也开始具有重要意义.近日,AnalyticsWeek的首席研究员.Bussiness Qver Broadway的总裁Bob Hayes博士就公开了研究数据分析项目成功所必需技能的相关结果.Bob所提出的基于技能的数据科学驱动力矩阵方法,可以指出最能改善数据科学实践的若干技能. 数据技能的熟练程度 首先,Bob在AnalyticsWeek的研究包含了很多向数据专家提出的,有

《系统分析与设计方法及实践》一2.3 结对编程方法

2.3 结对编程方法 极限编程的实践中有一个非常重要的原则就是结对编程,这里所谓的结对编程并非是一个人在编程,另一个在看.另外一个人也同样起着非常重要的作用,他需要帮助编码的人找到低级失误,防止其编码出现方向性的错误,特别是在出现一个正在编码的人不擅长解决的问题的时候,他会直接替换编码的人来进行编程.这样做的好处也许只有在实践了之后才能够体会到,它不仅可以避免一些错误的发生,而且可以通过直接的讨论来更快地解决一些容易产生歧义的问题.在交流的过程中,大家的水平也会有很快的提高.结对编程的过程也是一

无线标记语言(WML)基础之WML编程方法

编程 元素和标签是WML的主要语法,它们决定了WML编程的基本原则.本章我们将从WML的元素.标签.属性等方面详细讲解WML的编程方法.学习本章知识之前,读者应当了解WML元素与标签的区别.WML的元素通常有一个首标签.内容.其它元素及一个尾标签组成.也就说,单独的标签是一个元素,成对出现的标签与其包含的内容也构成一个元素.由于元素牵涉及标签,标签又涉及属性. 3.1 卡片.卡片组及其属性 我们前面介绍了WML的卡片与卡片组,主要从概念和相互关系的角度进行了分析.我们这里则从卡片.卡片组的组成.

最大限制地提高代码的可重用性,克服传统面向对象编程方法在可重用性方面的不足

编程|对象     重用是一种神话,这似乎正在日渐成为编程人员的一种共识.然而,重用可能难以实现,因为传统面向对象编程方法在可重用性方面存在一些不足.本技巧说明了组成支持重用的一种不同方法的三个步骤. 第一步:将功能移出类实例方法由于类继承机制缺乏精确性,因此对于代码重用来说它并不是一种最理想的机制.也就是说,如果您要重用某个类的单个方法,就必须继承该类的其他方法以及数据成员.这种累赘不必要地将要重用此方法的代码复杂化了.继承类对其父类的依赖性引入了额外的复杂性:对父类的更改会影响子类:当更改父

Excel 2000访问远程数据的四种方法

excel|访问|数据      Excel 2000作为一个电子表格软件,它不仅有强大的数据处理能力,而且它的报表功能也是十分强大.因而常常用Excel 2000去调用Access.SQL Server.Oracle.DB2等数据库软件建立的大型数据库的内容.用户可以在工作表中对这些数据进行筛选.排序.查询.编辑和打印报表,十分方便,这也是大多数人都熟悉的.但如何去调用这数据呢?本人在这里提供4种方法.    下面四种方法必须要先创建一个数据源,我们以SQL Server7.0内的样本数据库p

第二章-Delphi面向对象的编程方法(四)(1)

2.1.10.7 将库单元加入工程 将库单元加入工程是比较简单的.无论是您自己建立的库单元还是Delphi建立的与窗体有关的库单元,如果已经完成,则先打开您想加入库单元的工程(可以用Open Project打开工程):再选用File|Open File,然后选择您想加入的源程序(.PAS文件),并选择OK即可.则库单元被加入到应用程序中. 2.2 用Delphi的对象进行编程 Delphi是基于面向对象编程的先进开发环境.面向对象的程序设计(OOP)是结构化语言的自然延伸.OOP的先进编程方法,

Python实现数据库编程方法详解

  本文实例讲述了Python实现数据库编程方法.分享给大家供大家参考.具体分析如下: 用PYTHON语言进行数据库编程, 至少有六种方法可供采用. 我在实际项目中采用,不但功能强大,而且方便快捷.以下是我在工作和学习中经验总结. 方法一:使用DAO (Data Access Objects) 这个第一种方法可能会比较过时啦.不过还是非常有用的. 假设你已经安装好了PYTHONWIN,现在开始跟我上路吧-- 找到工具栏上ToolsàCOM MakePy utilities,你会看到弹出一个Sel

《Visual C++数字图像模式识别技术详解(第2版)》一2.1 Visual C++编程方法

2.1 Visual C++编程方法 面向对象是一种重要的程序设计方法,采用这一思想的C++是当今世界上应用最广泛的编程语言.Windows平台下的C++编程工具首推Microsoft的Visual C++.但是,编写Windows应用程序只熟悉C++的语法还是远远不够的,还必须掌握MFC(Microsoft Foundation Class,微软基础类库). 面向对象的编程是当前程序设计中的热门话题,这里将介绍使用Visual C++进行面向对象编程时所用到的一些关键概念,这些概念是进一步学习