backbone 模板 html,用Backbone.js绑住服务端生成的html
去年做雪球的timeline模块时我正深受 #newTwitter 的影响,倾向于把尽可能多的逻辑放到客户端去做,最后实现的时候选择了Backbone.js。使用Backbone.js的好处就不说了,这一两年它火的一塌糊涂,到处都是介绍的文章,而且这篇文章的重点也不是这个。
下面我假设您已经了解Backbone.js的作用和实现方式。
在页面初始化的时候,与发起一个ajax请求去取初始数据相比,把初始数据输出到页面里是一个更好的方案。Backbone.js提供了一个Loading Bootstrapped Models的FAQ,雪球也正是这样做的。把初始数据的json输出到页面里,然后Backbone.js用这个json来渲染页面。
但是这一年的实践中陆续发现一些问题:接口输出的timeline json里某些字段里偶尔出现一些不可见的换行符,导致浏览器解析json的时候出错。输出json字符串有injection可能(后来今年三月份的时候backbone特意在文档里加上了提示)。另外,随着业务复杂性的增长,接口直接输出的json体积在膨胀,很多属性已经不是页面展示所必须的,json的体积已经接近甚至已经超过了生成的html的体积。
同时我还在思考另外一个问题,backbone的使用场景其实是app,DocumentCloud、Trello这种需要反复对页面元素操作,应用要处理好数据和UI的一致性,初始化的时候稍微慢一点也没有关系,用backbone再好不过了。但是雪球其实更像是page,用户打开页面希望尽早的看到数据,当然我们也需要经常操作页面的元素,也需要处理数据和UI的一致性问题。
在服务端把html就拼好然后传给浏览器似乎是最直接的答案。那么接下来就面临了这篇文章要处理的问题了,如果既用服务端渲染html,又能够继续使用现有的基于backbone的客户端程序,甚至可以随时切换渲染位置。
backbone的文档似乎没有明确的给出这样的建议,但是稍微思考一下backbone View的实现方式应该可以想到,既然view的events是绑在一个根el上面的,那么这个el是一个空的wrapper或者已经渲染好的html片段并不影响事件的delegate。
var TimelineView = Backbone.View.extend({events: {"click .comment": "comment"}.comment: function(e){var $elm = $(e.target), statusModel = this.collection.get($elm.data("id"))renderComment(statusModel)},render: function(){var timelineHtml = ''// some code to generate html from models$(this.el).html(timelineHtml)}})var statusCollection = new StatusCollection(statusList)var timelineView = new TimelineView({el: $("#timeline"),collection: statusCollection})timelineView.render()
假设上面的一段代码是已有的客户端渲染的实现方式,需要说明的是statusList正是我们之前输出到页面里的timeline json,$("#timeline")是准备放timeline的wrapper。
现在改成服务端渲染之后发生的变化的后果,$("#timeline")变成了已经塞满status的列表,statusList不再存在。我们挨个解决。
$("#timeline")既然已经填满了,就不用再render啦。最后一行就改成了:
if ($("#timeline").html().trim()){timelineView.render()}
statusList是空的,那么statusCollection也是空的,comment的时候就找不到status的model。本来作为json输出来的数据其实被塞到了dom里,那我们就应该找一个合适的时候把status model从dom里读出来。我选择在view初始化的时候获取,给TimelineView加上initialize方法。
var TimelineView = Backbone.View.extend({initialize: function(){if (this.collection.length) {var models = []// some code to read models from timeline domthis.collection.add(models)}},...})
好了,客户端的代码没有任何其他要改的了,所有的backbone的功能都会跟原来一样的工作,还可以吧?
最后完整的代码改造成了这样:
var TimelineView = Backbone.View.extend({initialize: function(){if (this.collection.length) {var models = []// some code to read models from timeline domthis.collection.add(models)}},events: {"click .comment": "comment"}.comment: function(e){var $elm = $(e.target), statusModel = this.collection.get($elm.data("id"))renderComment(statusModel)},render: function(){var timelineHtml = ''// some code to generate html from models$(this.el).html(timelineHtml)}})var statusCollection = new StatusCollection(statusList)var timelineView = new TimelineView({el: $("#timeline"),collection: statusCollection})if ($("#timeline").html().trim()){timelineView.render()}
后记
这种处理对于需要SEO,或者特殊设备支持的应用来说更有意义。
服务端渲染html会给服务端带来额外的cpu消耗,但是很小。不过我们还是做了适配,可以随时切换渲染方式。
服务端渲染也需要模板,客户端渲染也需要模板,这个模板如何复用?对于使用node.js的雪球来说,很好处理。这个留给以后说。
backbone 模板 html,用Backbone.js绑住服务端生成的html相关推荐
- Pomelo:网易开源基于 Node.js 的游戏服务端框架
Pomelo 是基于 Node.js 的高性能.分布式游戏服务器框架.它包括基础的开发框架和相关的扩展组件(库和工具包),可以帮助你省去游戏开发枯燥中的重复劳动和底层逻辑的开发.Pomelo 不但适用 ...
- nuxt.js之SSR服务端内存泄漏导致CPU过高的解决过程
问题 最近在公司维护nuxt项目时,线上遇到了一个问题--访问网站,网站会报502或者JS.css资源报502. 去运维那一查pm2,项目node服务器的CPU达到了100%,实际上这段时间并没有人访 ...
- js与C#服务端 json数据交互
1.1 服务端返回给前端 返回的数据都放入对象中(根据需求:单个对象,集合,键值对),然后JSON序列化返回给前端.这里可以引用JSON.NET 库,也可以用.NET自带的类库: JavaScript ...
- 用 next.js 做一个服务端渲染的加密货币网站
学习 next.js next.js 是一个基于 React 的通用 JavaScript 框架,next.js 为 React 组件模型提供了扩展,支持基于服务器的组件渲染 (SSR),同时也支持在 ...
- 17 SSR:使用 React.js 开发 Serverless 服务端渲染应用
今天我想和你聊一聊怎么用 Serverless 开发一个服务端渲染(SSR)应用. 对前端工程师来说,Serverless 最大的应用场景之一就是开发服务端渲染(SSR)应用.因为传统的服务端渲染应用 ...
- Nuxt.js 开发SSR(服务端渲染)Web应用
1. 初识 Nuxt.js Nuxt.js 是一个基于 Vue.js 的通用应用框架. 与 vuepress 的关系: Nuxt.js 能够胜任 VuePress 的功能,但它专为构建应用程序而设计, ...
- 让 ASP.NET JS验证和服务端的 双验证 更简单
转自: http://www.cnblogs.com/sunkaixuan/p/4550580.html 只用JavaScript验证安全不安全谁都知道,答案是不安全,非常的不安全.因为在客户端进行的 ...
- nuxt.js实战asyncdata服务端渲染
Nuxt扩展了Vue的生命周期: export default {middleware () {}, //服务端,中间件validate () {}, // 服务端asyncData () {}, / ...
- 阿里云OSS服务端签名前端JS直传(php)示例
阿里云OSS服务端签名后前端JS直传(php)示例 需求:服务端上传图片太慢,需要使用前端直传的方式.但前端把阿里云的 AccessKey ID 和 AccessKey Secret 放在前端文件中会 ...
最新文章
- LinearAlgebra_1
- python 装饰器 参数-python装饰器参数那些事_接受参数的装饰器
- 15.Three Sum
- 用径向函数和球谐函数计算氢原子能级并验证维里定理
- 第一次连接mysql失败_MySQL 远程连接失败
- 移植驱动完毕后加载时的version magic报错原因以及解决办法
- 图解Transformer-一篇文章看懂transformer
- 华尔街顶级大师胡立阳名言
- 26期20180718 rsync
- 安装rarlinux及问题解决
- 如何按行政区划下载谷歌卫星地图并裁剪
- 【车牌识别】基于模板匹配算法实现国外车牌识别附matlab源码
- 转载:Max vs Maya
- nginx的access.log文件详解
- 从三个层面来谈下自己的团队管理心得及感悟
- 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
- jupyter notebook如何显示行号?
- Markdown表格、单元格合并、快速编辑表格
- docker安装wnameless/oracle-xe-11g并运行(手写超详细)
- 英语单词记忆以及句式记忆