4.12. 整合ajax的局部渲染技术

越来越多web网站依赖于ajax,如table的翻页,流行方式是浏览器发出ajax请求,后台处理后返回一个json,浏览器端将json数据拆开,拼成一条一条的行数据,然后生成dom节点,追加到表格里。 作为另外一种可选技术,beetl支持局部渲染技术,允许后台处理返回的是一个完成的html片段,这样,前端浏览器可以直接将这个html片段追加到表格里。在我做的性能测试里,俩种方式性能差别不大(http://bbs.ibeetl.com/ajax//)

比如模板index.html有很多动态内容,有动态生成的菜单,有右侧的top10,也有核心区域的表格,大概内容如下

  1. <#menu/>
  2. <#top10> ....</#top10>
  3. <div id="table-container" >
  4. <%
  5. //ajax片段开始
  6. #ajax userTable: {
  7. %>
  8. <table>
  9. <tr><td width=100>id</td><td width=100>姓名</td></tr>
  10. <% for(user in users){ %>
  11. <tr><td>${user.id}</td><td>${user.name}</td></tr>
  12. <% } %>
  13. </table>
  14. 当前页面<span id="current">${page!1}</span><span style="width:20px"></span>
  15. <a href="#"><span class="page">next</span></a> <a href="#" ><span class="page">pre</span></a>
  16. <%
  17. //ajax片段结尾
  18. }
  19. %>

ajax 用于告诉告诉模板引擎,此处是个局部渲染标记,标记为"userTable",对于正常渲染视图"index.html"页面,#ajax标记没什么用处,table仍能得到正常渲染。如果渲染的视图是index.html#userTable,则模板只会渲染#ajax标记得模板片段,其他部分将忽略。关于完整例子,可以参考https://git.oschina.net/xiandafu/beetlajax

后台代码如下:

  1. render("/index.html#userTable");

只需要在模板路径后加上#就表示渲染的并非是整个模板,而是模板的一部分,这一部分由#后面的标记来标示

ajax 片段渲染也支持默认情况下不渲染,仅仅做为一个片段使用,如一个页面有许多后台交互操作,并返回相应的html片段,可以将这些html片段也放到同一个模板里,使用ajax norender,表示渲染整个模板的时候默认并不需要渲染此ajax片段

  1. <%
  2. <html>
  3. </html>
  4. #ajax norender success: {
  5. %>
  6. <div id="success"> 操作成功
  7. </div>
  8. <%
  9. }
  10. %>
  11. #ajax norender failure: {
  12. %>
  13. <div id="failure"> 操作失败
  14. </div>
  15. <%
  16. }
  17. %>

这样,此页面默认情况下并没有输出success,和 failure片段

注意,Ajax片段本质上是从模版的ajax标记处开始渲染,因此,ajax需要的变量在模版里也必须是全局变量,如果你只是个局部变量,beetl会报出找不到变量,即使你binding了这个变量,beetl也认为这个是局部变量,如

  1. <%
  2. var tableData = paras.table;
  3. #ajax userTable: {
  4. for(user in tableData);
  5. %>
  6. <%
  7. //ajax片段结尾
  8. }
  9. %>

变量tableData是从paras里获取的,是个临时变量,因此就算你在后台binding了一个tableData,beetl 也不能识别。在渲染ajax片段的时候会报变量tableData找不到。改正的办法只能是让tableData全局变量。

返回Json好还是返回html片段好?这个难以定论.

  • 从后台性能看,将模型序列化成json性能会比渲染模板性能更好,但是,json还需要前端重新解析生成最终html dom节点,这可能会延迟最终数据的现实效果。而返回的html片段就是已经生成好的dom
  • 从网络传入来看,json无疑更好的,html片段会有额外的html标记,css属性,以及有可能的js调用。传入流量有可能增加50%到100%。但是,对于web应用类,这些额外数据,并不算多。
  • 从开发效率来讲,返回html片段的开发效率更高一些,因为渲染在后台操作,可以随心所欲的用模板语言来渲染,来取得后台数据,完成复杂渲染,而json就比较困难,可以说所有的json lib都没有完美的解决办法。
  • 从用户体验上来讲,Beetl 采用ajax标记,混合了传统的模板渲染和ajax加载。用户进入页面即能看到数据,而经典的ajax json方式还需要异步加载,显示延迟。另外如果页面同时有多个ajax加载,则会对服务器造成很大的压力。
  • 关心服务器cpu消耗? 模板方式消耗更多的cpu,json方式则少点。但是俩者差距并不大。而且更多的web网站面临的情况是有富余的服务器CPU能力
  • 关心客户端CPU消耗? 过多的js无疑是客户端运行慢的主要原因。如果采用经典的json方式,返回的json数据必然还需要经过js的计算和渲染。会影响客户机器cpu。

符号#ajax 实际上用来标记一个模板渲染片段,它还有个别名的叫#fragment,两者是一样的,比如

  1. <%
  2. #fragment part2:{
  3. println("part2");
  4. }
  5. %>