Abstract 1.0去哪了?1.0就在这里
Abstract 1.0并非凭空产生,而是来自兴趣部落这样千万级访问量大型项目的最佳实践,经过了千万客户端的检验,也证明了Abstract是一款优秀的框架。
用过Abstract的同学都知道答案是否定的,就拿当下最流行的框架来举例,使用了AngularJS、React之后,是否就可以不用Abstract了,答案也是否定的,Abstract解决的问题的层面是高于AngularJS和React的,在抽象层面上Abstract更高于AngularJS、React。更为简单的叙述是,AngularJS、React会帮你写业务逻辑么?肯定不会,但Abstract会帮你写业务逻辑,这就是Abstract和其他框架的区别所在.
如果React宣称自己处于抽象层面的V(view)层,那么Abstract是处于C(controller)层的框架
Abstract带来的优势是很可观的
我们来做一个对比,看普通的写法是怎么做的,用Abstract是怎么做的
假设我们来完成部落头部的信息的渲染,普通的写法可能是这样的
var renderTop = function(){ // 请求cgi $.ajax({ url: "/cgi-bin/top_info", data: { bid: 10038 }, success: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } // 渲染模板了 Tmpl(topTmpl, data).appendTo($("#top")); }, error: function(data){ } }); }; renderTop();
这么简单的逻辑,感觉写起来还不错
看看使用Abstract是怎么做的
var topInfo = new RenderModel({ cgiName: "/cgi-bin/top_info", param: { bid: 10038 }, renderTmpl: topTmpl, renderContainer: $("#top"), processData: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } } }); topInfo.rock();
哈,感觉没什么高大上的,也没什么吧。。。这还不是Abstract强大之处
现在需求来了,产品要求加快top渲染的速度,怎么办?有什么办法?
一个办法就是做本地缓存,一进来使用上次请求过的据渲染,安份的写法应该是这样的吧
var renderTop = function(){ //先使用缓存渲染数据 var dataCache = JSON.parse(localStorage.getData("top") || '{}'); Tmpl(topTmpl, dataCache).appendTo($("#top")); // 请求cgi $.ajax({ url: "/cgi-bin/top_info", data: { bid: 10038 }, success: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } // 渲染模板了 Tmpl(topTmpl, data).appendTo($("#top")); //写下缓存供下次使用 // 防止写的时候溢出啊亲 try{ localStorage.setData('top', JSON.stringify(data)); }cache(e){ localStorage.clear(); localStorage.setData('top', JSON.stringify(data)); } }, error: function(data){ } }); } renderTop();
看起来也还不错,好像挺好的,这次,第二次之后进来,top刷刷就出来了,Abstract怎么写呢
/* Abstract构建的页面 */ var topInfo = new RenderModel({ cgiName: "/cgi-bin/top_info", param: { bid: 10038 }, renderTmpl: topTmpl, renderContainer: $("#top"), processData: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } } }); topInfo.rock();
看了半天,发现跟之前的写法没什么区别啊?是啊,使用Abstract你不需要关心缓存层的渲染的,它自动帮你做了。但有些时候我不需要它做,只需要加上noCache: false这样的选项关闭即可
这样感觉也没什么值得炫耀的功能,是的,但是,接定来看
接着我们可能要渲染底部的信息,普通是这么做的
var renderTop = function(){ //先使用缓存渲染数据 var dataCache = JSON.parse(localStorage.getData("top") || '{}'); Tmpl(topTmpl, dataCache).appendTo($("#top")); // 请求cgi $.ajax({ url: "/cgi-bin/top_info", data: { bid: 10038 }, success: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } // 渲染模板了 Tmpl(topTmpl, data).appendTo($("#top")); //写下缓存供下次使用 // 防止写的时候溢出啊亲 try{ localStorage.setData('top', JSON.stringify(data)); }cache(e){ localStorage.clear(); localStorage.setData('top', JSON.stringify(data)); } }, error: function(data){ } }); }; var renderBottom = function(){ //先使用缓存渲染数据 var dataCache = JSON.parse(localStorage.getData("bottom") || '{}'); Tmpl(topTmpl, dataCache).appendTo($("#bottom")); // 请求cgi $.ajax({ url: "/cgi-bin/bottom_info", data: { bid: 10038 }, success: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } // 渲染模板了 Tmpl(bottomTmpl, data).appendTo($("#bottom")); //写下缓存供下次使用 // 防止写的时候溢出啊亲 try{ localStorage.setData('bottom', JSON.stringify(data)); }cache(e){ localStorage.clear(); localStorage.setData('bottom', JSON.stringify(data)); } }, error: function(data){ } }); }; renderTop(); renderBottom();
这样写或许也挺简单的,但是不同的人有不同的写法,可能一个renderTop和一个renderBottom写法就不同,更别说更加复杂的逻辑,那Abstract怎么写
/* Abstract构建的页面 */ var topInfo = new RenderModel({ cgiName: "/cgi-bin/top_info", param: { bid: 10038 }, renderTmpl: topTmpl, renderContainer: $("#top"), processData: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } } }); var bottomInfo = new RenderModel({ cgiName: "/cgi-bin/bottom_info", param: { bid: 10038 }, renderTmpl: bottomTmpl, renderContainer: $("#bottom"), processData: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } } }); var page = new PageMode(); page.add(topInfo); page.add(bottomInfo); page.rock();
细心的同学会发现,Abstract在最后,不是让topInfo和bottomInfo分别rock,而上加到了一个pageModel的实例上,让pageModel实例去rock。
可以看出,Abstract的优点
1.规范化代码,所有人的代码风格统一,阅读方便
2.写法简单,快速
3.尽可能多的帮业务开发者做更多的事情
4.页面模块化的思想与配置型代码(类似React,但那时不了解有React)
5.更优雅的代码
上面的例子还不足矣让Abstract来支撑更复杂的页面,那如果更复杂页面怎么写?
移动中比较常见的场景就是滚动加载,这时用Abstract要怎么写呢?
普通的写法,可能要洋洋洒洒写上一大篇了吧,Abstract是这样写的
/* Abstract构建的页面 */ var topInfo = new RenderModel({ cgiName: "/cgi-bin/top_info", param: { bid: 10038 }, renderTmpl: topTmpl, renderContainer: $("#top"), processData: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } } }); var bottomInfo = new RenderModel({ cgiName: "/cgi-bin/bottom_info", param: { bid: 10038 }, renderTmpl: bottomTmpl, renderContainer: $("#bottom"), processData: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } } }); // 这里是一个滚动加载模型 var postList = new ScrollModel({ cgiName: "/cgi-bin/posts", param: function(){ var every = 10; var start = - every; return function(){ return { start: start += every, num: every, bid: 10038 }; }; }(), renderTmpl: postTmpl, renderContainer: $("#postList"), processData: function(data){ for(var i = 0; i < data.posts.length; i ++){ var item = data.posts[i]; item.flag = getFlag(item.flag); } } }); var page = new PageMode(); page.add(topInfo); page.add(bottomInfo); page.add(postList); page.rock();
就这么简单,一个简单的页面就完成了