构成
这是一个十分常见的微博列表页面,类似于新浪微博。上周末,在心无旁骛情况下,一共用了5个对象,产出400行代码,实践出一种代码组织模式。
使任务轻松完成的代码有4个方面的要素组成:
| 要素 |
组成 |
| 模型 |
Reply、Forward |
| 视图 |
CommentEditor、ReplyList、ForwardList |
| 模板 |
jQuery.tmpl |
| 异步任务 |
jQuery.Deferred |
分部介绍 模型
模型只与数据有关,它能够产生、过滤、保存、验证数据,并且仅此而已。
如下例,留言模型在调用保存方法时,只接收JSON参数,并且只返回一个异步任务,实际处理时同步或异步的返回结果并不重要。
在此进行的验证的原因是,它是一个开放的对象,是与服务器交互的最后一道门槛。
另外,它本身也不处理验证失败的情况——由视图调用时选择性地处理,可能会弹出一个消息提示或直接忽略再进行重试。
复制代码 代码如下:
// 留言模型
var Reply = {
cache : {},
// { sourceid : id,page_size : 10,page_num : 1 }
fetch : function(data) {
return $.post('/ajax/blog/reply/list',data||{}).success(function(resp) {
resp.ok && resp.list &&
$.each(resp.list,function(k,v) {
return Reply.cache[v.id] = v;
});
});
},
// filter('name','king')
filter : function(prop,val) {
return $.grep(this.cache,function(r){ return r[prop] === val });
},
// { content : '想说就说',sourceid : 1001 }
create : function(data) {
// promise
var dfd = $.Deferred(), now = $.now();
if( (now - this.create.timestamp)/1000 < 10 ){
dfd.reject({message:'您发表得太快了,休息一下吧',type:'warn'})
}else if(!data || !data.sourceid){
dfd.reject({message:'非法操作',type:'error'})
}else if(!data.content){
dfd.reject({message:'评论内容不能为空',type:'warn'})
}else{
this.create.timestamp = now;
dfd = $.post('/ajax/blog/reply/create',data);
}
return dfd.promise();
}
};
Reply.create.timestamp = Forward.create.timestamp = $.now() - 1e4;
视图
视图是浏览器页面上的可视部分,每个视图对象含有一个关联的 jQuery 对象作为属性(instance.$el),类似于UI组件中的DOM容器。
视图还有两个一致的方法:
render 方法用于从模型获取数据,并且根据定义好的模板将数据渲染到HTML页面上。
activate 方法用于激活视图,同时绑定相关的DOM事件,所有事件至多委托到$el为止。
这个示例中,CommentEditor是父视图,ReplyList和ForwardList是互斥显示的两个子视图,父子视图之间相互保存引用。
复制代码 代码如下:
// 回复列表视图
var ReplyList = function(options) {
var opt = this.opt = $.extend({
el : '',
parent : null
},options||{});
this.parent = opt.parent;
this.$el = $(opt.el);
this.activate();
};
ReplyList.prototype = {
render : function() {
var self = this;
Reply.fetch({
page_size : 10, page_num : 1,
sourceid : self.parent.getBlogId()
})
.done(function(data) {
self.$el.html( self.$list = $.tmpl(tpl_reply_list,data) );
});
return self;
},
activate : function() {
this.$el.delegate('a.del',$.proxy(this.del,this))
}
// ...
}
// 评论编辑器视图
CommentEditor.prototype = {
activate : function() {
this.$el.delegate('a.save',$.proxy(this.save,this))
},
save : function() {
var self = this, data = { content : self.getContent(),sourceid : self.getBlogId() };
var task_r = Reply.create(data);
var task_f = Forward.create(data);
// 转发、评论同时进行
$.when(task_r,task_f).then(function(t1,t2) {
// 保存成功,更新视图或关闭
},function(data) {
// 模型验证出错,或远程服务器错误
Sys.info(data.message,data.type);
});
return self;
},
switchView : function(type) {
// 切换子视图
var view_opt = {el:this.$sublist.empty(),parent:this};
if(type === 'reply'){
$label.show();
this.$submit.val('评论');
this.sublist = new ReplyList(view_opt).render();
}else{
$label.hide();
this.$submit.val('转发');
this.sublist = new ForwardList(view_opt).render();
}
}
// ...
}
模板
模板可以消除繁琐、丑陋的字符串拼接,它的作用是能够直接由js对象生成HTML片断。
模板中可以直接遍历对象,套用预定义的函数,来对一些数据进行格式化,比如时间函数nicetime:
复制代码 代码如下:
// 回复列表模板
var tpl_reply_list = '<ul class="ui-reply-list">\
{{each list}}\
<li data-id="${id}">\
<a class="name" href="/${userid}">${name}:</a>\
<p>${content}</p>\
<time pubdate>${nicetime(timestamp)}</time><a class="del" href="javascript:;">删除</a>\
</li>\
{{/each}}\
</ul>';
异步任务
Deferred Object 的直译是延迟对象,但是理解成异步任务更为恰当。异步任务能够消除多层嵌套的回调,让代码书写和阅读更为便利。
从上面的模型和视图的代码中可以明显地看出,使用了异步任务之后,代码变得更加平面化了。
$.Deferred 方法新建的是一个双向任务队列:成功回调函数队列和失败回调函数队列;任务的状态也分为两种:成功和失败,分别可以用isResolved或isRejected来检查任务的当前状态、用resolve或reject修改任务状态。
promise 方法返回任务的只读副本,此副本上不能修改任务状态。毫无疑问,模型应该始终只返回 promise 对象。(注:只读副本仍然可以再次调用 promise 方法再次返回只读副本)
在Reply.create方法中,能够更好地处理自定义的异步任务,而不是直接返回原生的ajax异步任务:
复制代码 代码如下:
// var dfd = $.Deferred();
$.post('/ajax/blog/reply/create',data)
.success(function(json) {
if(json && json.ok){
dfd.resolve(json.list);
}else{
dfd.reject({message:json.message||'获取失败',type:'error'});
}
})
.fail(function() {
dfd.reject({message:'服务暂时不可用',type:'error'})
});
目的及结论
为什么拆散成这样?
收获:可维护性,清晰的API调用、消除二层以上的if语句、消除二层以上的回调语句、每个函数控制在二十行之内。
结果:没有过多的重复代码,所有的功能都被打包好了。
相关推荐:
SEO做法-提升网站流量与排名的关键秘诀,屏东网站推广招聘
SEO注意事项:助力网站流量提升的关键策略,济宁快速seo优化价格
ChatPartner无法连接网络?解决方案,让你的聊天体验更顺畅!,如何用ai给自己写作文
什么是seo推广找行者SEO,seo推广效果怎么样 ,西宁ai万词霸屏系统
ChatGPT与讯飞:AI语音与智能对话的完美融合,ai直角变圆角
GPT在智能聊天机器人中的作用:重塑沟通体验,开创智能未来,百万级ai
“爱站”:开启网站优化与流量增长的新纪元,seo入门ppt
ChatGPT您的应用遇到问题,无法正常启动?如何解决并重新体验智能助手的魅力!,男头ai关键词
ChatGPT回答是空白的背后,究竟隐藏着什么秘密?,如何用ai写作来赚钱
Chato1免费么?揭开这款AI聊天机器人的神秘面纱,交个朋友ai写作
为什么选择B站VIP?让你畅享更丰富的视听体验,小门类网站seo
SEO领先-如何借助SEO技术让您的网站脱颖而出,seo是黑客吗
AI一键生成文章免费版:颠覆写作新体验
SEO行销:开启网站流量增长的秘密武器,百威产品关键词查询排名
文章去AI回归创作的本真之美
SEO妍:搜索引擎优化的艺术,轻松打造网络营销新未来,辽宁网站建设贵不贵
ChatGPT免费版每天提问有次数限制吗?揭秘如何高效使用AI助手!,机甲ai手绘
SEO新闻:2025年最新趋势与最佳实践,你不可错过的SEO战略,郑州网络营销推广的优势
ChatGPT403:引领人工智能新时代,颠覆你的工作与生活方式,ai nak
ChatGPT40不收费版本:科技革新,智能助手助力生活与工作,ai医疗武器有哪些
用AI批量下载工具,高效管理你的文件和资源
wordpress seo是什么,wordpress建站seo好做吗 ,学习图文ai
SEO用户:如何为您的网站带来持续流量和转化,惠州网站推广哪个好
ChatGPT宕机恢复时间如何解决用户焦虑与技术背后的故事,ai人工智能写作火山
SEO那么重要,企业如何通过它脱颖而出?,自媒体推广营销的概念
ChatGPT网站突然不能用了?如何快速解决这个问题,让你重新畅享AI对话!,ai新建多个画板
ChatGPT的超链接点不开?解决方法一网打尽!,情感ai写作指令是什么
SEO特点与实施策略:提升网站流量与排名的关键,定西抖音seo价格查询
SEO文案:如何通过巧妙布局提升网站排名,吸引更多流量,娄底网站建设工作文案
SEO能够助力网站流量增长,提升品牌竞争力,Seo网站排名原理
SEO伪创:提升网站排名的危险策略与如何避免,怎样介绍社交网站推广
SEO优化关键技巧:提升网站排名的实战攻略,科大讯飞ai论文写作软件
GoogleGTP-智能时代的革命性突破,人工智能的新纪元,ai可以降论文ai率吗
SEO运营工作是什么,seo公司运营 ,720516AI
SEO优化排名:让您的网站在搜索引擎中脱颖而出,我ai 达瓦仓决
SEO埋词技巧,如何提升网站排名?,贵州营销推广方法
AI免费生成文章的软件:轻松创作的秘密武器
ChatGPT360:全方位提升你的工作与生活效率,ai72787
SEO检测,让网站排名飞升的秘密武器,高端快消食品营销推广
重生成AI:突破科技前沿,开启智能未来
二创AI:打破创意壁垒,引领未来内容创作新潮流,背影教案网站建设游戏
seO经理是什么岗位,seo经理招聘 ,ai写作重复被查
ChatGPT免费订阅的使用限制:其潜力与挑战,ai辅助线无法对齐画板
交友群都有哪些,交友群是干什么的 ,ai猫csgo
ChatGPT崩一次多久修复?揭秘背后的技术与保障,ai1818818
未来写作新模式文章撰写AI如何助力内容创作
SEO就业前景如何?打造数字时代的职业新风口,常州武进区水产网站建设
ChatGPT无法加载?检查您的网络设置并尝试重启,轻松解决连接问题!,ai制作艺术字
为什么“蜘蛛弛查询”能成为提升网站排名的秘密武器?,惠州网站推广v1戈seo24
ChatGPT服务器坏了?了解背后的技术与应对策略,AI模块代表