先看事例,根据下面的HTML和后端接口来更新界面。

HTML:

view sourceprint?
<ul>
    <li>用户名:<span id="userName"></span></li>
    <li>昵称:<span id="loveName"></span></li>
    <li>生日:<span id="birthday"></span></li>
</ul>
<input type="button" value="更新" id="update" rel="123456789" />

后端接口:http://www.xxx.com/getuserinfo.php

参数:uid Number

返回数据:{"userName":"lujun", "loveName":"鲁军", "birthday":"1989/02/02"};

要求:当用户点击update 按钮,根据rel值从服务器取得用户的信息,并且显示到HTML对应的位置

不用思考,你的代码应该是这样的(利用jQuery):

$("#update").click(function(){
var uid = $(this).attr("rel");
$.get("http://www.xxx.com/getuserinfo.php",{"uid":uid},
function(data){
//var data = {"userName":"lujun", "loveName":"lujun", "birthday":"1989/02/02"};// 模拟数据
$("#userName").text(data.userName);
$("#loveName").text(data.loveName);
$("#birthday").text(data.birthday);
}
);
});

对于简单的页面更新这并没有任何问题,也是最佳方案。简单,易懂

今天讨论复杂的WEB站点,页面上可能有10-20个这样的按钮。还采用这样的更新方式,你会发现

1:对于后端API调用的代码无法复用

2:页面代码javascript非常乱(逻辑更复杂了,返回数据正确定判断和提示,HTML模板解析,多级请求嵌套)

3:多人维护同一站点,看不懂别人的代码(因为都采用了自己的方式)

使用观察者模式

我们把获取数据的ajax看作一个数据 “发布者”,把更新UI界面的看作一个 “数据订阅者”

于是有了下面的基本代码

;(function(){
// 发布者
var Model = function(key){
this.key = key;
this.observers;
}
Model.prototype = {
// 添加订阅者
addObserver:function(a){
if(!this.observers){this.observers = []};
this.observers.push(a);
},
// 获取数据的通道
loadData:function(){
throw "undefined";
},
// 通知订阅者数据发生改变
changeValue:function(data){
var observers = this.observers;
for(var i = 0; i<observers.length; i++){
observers[i].update(data, this);
}
}
}

// 订阅者
var Observer = function(model){
this.models;
}
Observer.prototype = {
update:function(){
// 用来维护用户界面
throw "undefined";
},
// 添加发布者
addModel:function(a){
if(!this.models){ this.models = []};
this.models.push(a);
},
// 主动拉去信息
pull:function(){
var models = this.models;
for(var i=0; i< models.length; i++){
models[i].loadData.apply(models[i], arguments);
}
}
}

window.PAGE = {
"Model":Model,
"Observer":Observer,
};

})();

使用 PAGE 这个命名空间保存这两个“类”。

发布者

Model {

addObserver:添加订阅者

loadData:获取服务器数据,需要重载的方法

changeValue:通知界面更新

订阅者

Observer{

  update:更新界面,需要重载的方法

  addModel:添加发布者(主要用来实现拉去信息)

  pull:拉去信息(拉去信息一般都很少用)

有了上面的代码,那么要完成上面的题目应该这样做

// Model 关注数据传输
function getUserInfoModel(){}
getUserInfoModel.prototype = new PAGE.Model();
getUserInfoModel.prototype.loadData = function(uid){
var _this = this;
$.get("http://www.xxx.com/getuserinfo.php",{"uid":uid},
function(data){
//var data = {"userName":"lujun", "loveName":"鲁军", "birthday":"1989/02/02"};//模拟数据
_this.changeValue(data);
}
);
};

// Observer 关注用户界面
function updateUserInfo(){}
updateUserInfo.prototype = new PAGE.Observer();
updateUserInfo.prototype.update = function(data){
$("#userName").text(data.userName);
$("#loveName").text(data.loveName);
$("#birthday").text(data.birthday);
}

// 关注UI交互
$("#update").click(function(){

var uid = $(this).attr("rel");

var model = new getUserInfoModel();
var observer = new updateUserInfo();

model.addObserver(observer);
model.loadData(uid);

});

获取数据和页面更新 分离了,如果再有其他地方需要获取用户信息,可以直接 new getUserInfoModel().loadData(),不必要在写一次javascript请求(这很重要)。

如果团队约定每次更新数据,都按照这样的方式来工作。无论你看谁的代码,逻辑始终那么清晰。他调用了一个API,更新了页面上的这些内容。

工作也会变得傻瓜式,首先 new 出 发布者和观察者,添加关注并覆盖获取数据,和更新界面的方法。大功告成

不难发现,上面的代码任然存在一些问题。比如他增加了 2 个全局变量 getUserInfoModel ,updateUserInfo。这样绝对不行,不可能每一个API的调用都添加两个全局变量。

使用单体模式

单体(singleton)模式是javascript中最基本最有用的模式之一,它可能比任何模式都常用。《javascript设计模式》 P65。(如果不太了解可以查阅下资料)

单体可以用来划分命名空间,减少全局变量,使代码更容易阅读和维护。

回到上面的代码,getUserInfoModel ,updateUserInfo 继承了 Model , Observer。他们的主要工作 覆盖 loadData,update。并且提供一个全局可访问的名字。

使用单体可以这样做:

//依然使用PAGE 这个命名空间。

PAGE.loadDatas = {};// 存放所有数据更新的方法
PAGE.updates = {};// 存放所有页面的更新方法

PAGE.loadDatas.getUserInfo = function(uid){
var _this = this;
$.get("http://www.xxx.com/getuserinfo.php",{"uid":uid},
function(data){
var data = {"userName":"lujun", "loveName":"鲁军", "birthday":"1989/02/02"};//模拟数据
_this.changeValue(data);
}
);
}

PAGE.updates.updateUserInfo = function(data){
$("#userName").text(data.userName);
$("#loveName").text(data.loveName);
$("#birthday").text(data.birthday);
}

$("#update").click(function(){

var uid = $(this).attr("rel");

var model = new PAGE.Model();// 直接继承 Model
var observer = new PAGE.Observer();// 直接继承 Observer

model.loadData = PAGE.loadDatas.getUserInfo; // 重载(覆盖) loadData
observer.update = PAGE.updates.updateUserInfo; // 重载(覆盖) update

model.addObserver(observer);
model.loadData(uid);

});

使用直接继承(原来是继承2次),loadData,update方法被覆盖,同时提供了全局可访问的名字。代码组织很好。出色完成。

当你写过几次以后,会发现 click 方法体内的模式几乎万年不变,你可以尝试门面模式进行一个包装。

最后:

对于多人协作,必须要找一个大家都认同的编码方式(相信你也认同这一点)。

对于javascript 使用单体 比 (function(){/**你的N多代码**/})()。好很多

观察者应该有事件注册和派发(fire)的能力。这可以解决多级AJAX请求嵌套的问题

上面讨论的方式,并不适合简单的站点(少交互)。

本文来之博客园:idche  原文链接

转载于:https://www.cnblogs.com/chenyang2005/archive/2010/11/22/1884538.html

[转]【分享】浅谈 JavaScript 在多交互站点中的工作方式相关推荐

  1. 浅谈JavaScript作用域,关于Java的学习路线资料

    javascript是目前web领域中使用非常广泛的语言,不管是在前端还是在后端都能看到它的影子,可以说web从业者不论怎样都绕不开它.在前端领域,各种框架层出不穷.在后端领域,nodejs可谓如火如 ...

  2. html 滚动条 scrolltop scrollheight,浅谈JavaScript中scrollTop、scrollHeight、offsetTop、offsetHeight...

    浅谈JavaScript中scrollTop.scrollHeight.offsetTop.offsetHeight 发布时间:2020-07-17 09:27:20 来源:亿速云 阅读:223 作者 ...

  3. 浅谈javascript中原型(prototype)、构造函数、对象实例及三者之间的关系

    转自:http://www.cnblogs.com/zhangwei412827/archive/2012/12/14/2816263.html 浅谈javascript中原型(prototype). ...

  4. 浅谈 JavaScript 编程语言的编码规范--转载

    原文:http://www.ibm.com/developerworks/cn/web/1008_wangdd_jscodingrule/ 对于熟悉 C/C++ 或 Java 语言的工程师来说,Jav ...

  5. JavaScript 中的 require / exports、import / export、浅谈JavaScript、ES5、ES6

    Node.js 的基础教学 之 exports 和 module.exports:https://zhuanlan.zhihu.com/p/82057593 浅谈 JavaScript.ES5.ES6 ...

  6. 浅谈 JavaScript 编程语言的编码规范

    转自:http://www.ibm.com/developerworks/cn/web/1008_wangdd_jscodingrule/?ca=drs-tp4608 developerWorks 中 ...

  7. 浅谈JavaScript中的NaN

    浅谈JavaScript中的NaN NaN概念以及简单案例 追寻的纯粹该拥有自己的本质.-JC.F 什么是NaN? NaN:NaN(Not a Number),它表示不是数字,但是仍是数值类型. Na ...

  8. 计算机室在初中英语教学中的应用,浅谈信息技术在初中英语教学中的运用

    浅谈信息技术在初中英语教学中的运用 关键词:初中 英语 信息技术 摘要:如今信息技术高速发展,其应用范围愈加广泛.信息技术在教学中的应用,为学生接受知识提供了更为便捷的途径.在初中的英语教学中,结合信 ...

  9. java e.getmessage() null,浅谈Java异常的Exception e中的egetMessage()和toString()方法的区别...

    Exception e中e的getMessage()和toString()方法的区别: 示例代码1: public class TestInfo { private static String str ...

  10. 浅谈数学在计算机科学中的应用,浅谈计算机科学技术在数学思想中的应用(原稿)...

    <浅谈计算机科学技术在数学思想中的应用(原稿).doc>由会员分享,可免费在线阅读全文,更多与<浅谈计算机科学技术在数学思想中的应用(原稿)>相关文档资源请在帮帮文库(www. ...

最新文章

  1. 核显也能玩游戏,OS X Yosemite优化指南
  2. Spring框架中的设计模式(一)
  3. wxWidgets:支持国际化
  4. nginx工作进程处理请求的系统调用
  5. FFPLAY的原理(一)
  6. 设计模式之二-Proxy模式
  7. 16.Java中的String详解
  8. 使用cboard(oracle数据库)
  9. Flex Builder 破解和注册方法
  10. 何为编码 GBK 和 UTF8编码?GBK,GB2312与区位码有何关系?
  11. ai怎么渐变颜色_AI渐变工具怎么使用?AI渐变工具使用方法介绍
  12. 阿里云虚拟主机、企业邮箱免费申请
  13. 各种语言如何连接到 OceanBase
  14. 电脑上可贴至桌面显示的便签软件
  15. BC61 金字塔图案
  16. 民航飞行学院计算机研究生就业,数据说话:文科硕士研究生就业变迁史
  17. 冲刺阶段第八天,4月26,27,28日。
  18. WIN10下Prolific USB-to-Serial Comm Port驱动
  19. SL-PCA(子空间学习模型)——前景提取
  20. c++练习 日期的顺延显示

热门文章

  1. PhotoShop 2022 mac版新增功能
  2. Toontrack Superior Drummer for Mac(鼓音乐制作工具)
  3. 使用Xilisoft iPad Magic Platinum for Mac将任何视频/音频转换和传输到 iPad/iPod/iPhone/iTunes?
  4. (日常搬砖)数据集标注格式转换:txt转xml(VOC格式)
  5. Flask框架-模板
  6. android(安卓)开源框架——六款【转】
  7. git 如何忽略掉指定目录
  8. poj Labeling Balls 3687 拓扑排序!!!!
  9. 苹果mac专业音频处理软件:Audition
  10. MacBook Pro 高功率模式:是如何工作的?