精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-01
最后修改:2009-04-07
直接在服务断模板中划出一块做客户端模板 在模板编译过程中,会把<c:client节点下的模板内容编译成js代码。渲染到客户端中可以直接通过js调用,因为不需要在客户端直接解析模板源代码,所以,能达到一个更高的性能。
支持的方式大概是这样的: <html> <head> <title>模板测试</title> <!-- 申明一段客户端模板 --> <c:client id="userListTemplate "> <h3>用户列表</h3> <c:for items="${userList}" var="user"> <p>用户名:${user.name}</p> <p>所在公司:${user.company}</p> <hr/> </c:for> </c:client> </head> <body> 。。。。。。 <script> function onPageChange(userList){ E("userList").innerHTML = userListTemplate (userList) } </script> </body> </html>
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-04-02
发现很多人一开始就想错了。
<c:client节点是不会到达客户端的, 客户端看到的只是 <script> function userListTemplate (context){ //这里是生成的模板源代码 } </script> |
|
返回顶楼 | |
发表时间:2009-04-06
呵呵,泼点冷水:
你这个想法和我几年前的想法不谋而合,总体的思路是:通过一层中间层,提供更简便灵活的视图书写方法。 但是现在回头来看,这种思路颇有隔靴搔痒的感觉,因为很难用 Firebug 直接 Debug 我写的代码,我最多能 Debug “你的通过我写的代码而生成的代码” 你的框架就是靴子,我再怎么样,都要隔着靴子去解决我的问题(找我的 Bug)。所以,在开发时,还不如直接写几个真正有用的 jQuery 的插件来的痛快。 但同时,是我也真心期望你的项目能够成功,因为你的成功就意味着你成功的改变了别人的使用习惯,能做到这一点很不简单。我现在设计的框架,基本上都本着“不改变或者尽量不改变用户的使用习惯”为原则的,起码,在这点上,你很用勇气,所以赞一个先,期待你的突破。 |
|
返回顶楼 | |
发表时间:2009-04-07
最后修改:2009-04-07
已经在Lite XML1.0Alpha7中实现了。
用法如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://www.xidea.org/ns/lite/core"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>前后端统一模板实例</title> <link href="tablecloth.css" rel="stylesheet" type="text/css" media="screen" /> </head> <body> <div id="container"> <h1>前后端统一模板实例</h1> <div id="content"> <h2>${title}</h2> <table cellspacing="0" cellpadding="0"> <tr> <th>姓名</th> <th>公司</th> <th>年龄</th> <th>城市</th> </tr> <c:for var="item" items="${data}"> <tr> <td>${item.name}</td> <td>${item.company}</td> <td>${item.age}</td> <td>${item.city}</td> </tr> </c:for> </table> </div> <div> <c:for var="item" items="${[1,2,3,4,5,6]}"> <a href="#" onclick="reset(${item});return false;">${item}</a> </c:for> </div> </div> <!-- 这里的内容会编译成JS函数 --> <c:client id="userTemplate"> <!-- 偷懒有道,xpath直接包含前面那段模板片断 --> <c:include xpath="//*[@id='content']/*" /> </c:client> <script>/*<![CDATA[*/ function reset(id){ var content = document.getElementById('content'); var model = ${JSON.stringify({title:"客户端模板",data:data})} //我们对模型做一点简单的修改(当能你也可以XHR从服务断获取数据,或者从客户端数据模型获取) model.title +=id; for(var i=0;i!=model.data.length;i++){ var item = model.data[i]; for(var n in item){ item[n]+=id; } } content.innerHTML = userTemplate(model); }/*]]>*/ </script> </body> </html> |
|
返回顶楼 | |
发表时间:2009-04-07
最后修改:2009-04-07
zozoh 写道 呵呵,泼点冷水:
你这个想法和我几年前的想法不谋而合,总体的思路是:通过一层中间层,提供更简便灵活的视图书写方法。 但是现在回头来看,这种思路颇有隔靴搔痒的感觉,因为很难用 Firebug 直接 Debug 我写的代码,我最多能 Debug “你的通过我写的代码而生成的代码” 你的框架就是靴子,我再怎么样,都要隔着靴子去解决我的问题(找我的 Bug)。所以,在开发时,还不如直接写几个真正有用的 jQuery 的插件来的痛快。 但同时,是我也真心期望你的项目能够成功,因为你的成功就意味着你成功的改变了别人的使用习惯,能做到这一点很不简单。我现在设计的框架,基本上都本着“不改变或者尽量不改变用户的使用习惯”为原则的,起码,在这点上,你很用勇气,所以赞一个先,期待你的突破。 太晚了,明天再来答复你的疑问吧,先概括一下: 你的担心不是没有道理,但是根据以往经验。我们没有碰到,也许基于Lite的实现就很难碰到。 |
|
返回顶楼 | |
发表时间:2009-04-07
最后修改:2009-04-07
zozoh 写道 呵呵,泼点冷水:
你这个想法和我几年前的想法不谋而合,总体的思路是:通过一层中间层,提供更简便灵活的视图书写方法。 但是现在回头来看,这种思路颇有隔靴搔痒的感觉,因为很难用 Firebug 直接 Debug 我写的代码,我最多能 Debug “你的通过我写的代码而生成的代码” 你的框架就是靴子,我再怎么样,都要隔着靴子去解决我的问题(找我的 Bug)。所以,在开发时,还不如直接写几个真正有用的 jQuery 的插件来的痛快。 但同时,是我也真心期望你的项目能够成功,因为你的成功就意味着你成功的改变了别人的使用习惯,能做到这一点很不简单。我现在设计的框架,基本上都本着“不改变或者尽量不改变用户的使用习惯”为原则的,起码,在这点上,你很用勇气,所以赞一个先,期待你的突破。 回来解释一下这些疑问吧。 [list] 半年前,那就那着LiteXML的早期版本做开发。压根就没有遇到调试需求。 设计这个模板的时候,有一个目标,那就是尽量不需要文档。 我们在开发过程中,没有做过任何相关培训,只有极少的关于语法的私下询问(貌似只有一次,当能,这也说明我们团队成员的水平还是非常不错的^_^) 可以看一下对比:模板源代码 <!-- 这里的内容会编译成JS函数(函数名userTemplate) --> <c:client id="userTemplate"> <h1>前后端统一模板实例</h1> <div id="content"> <h2>${title}</h2> <table cellspacing="0" cellpadding="0"> <tr> <th>姓名</th> <th>公司</th> <th>年龄</th> <th>城市</th> </tr> <c:for var="item" items="${data}"> <tr> <td>${item.name}</td> <td>${item.company}</td> <td>${item.age}</td> <td>${item.city}</td> </tr> </c:for> </table> </div> </c:client> 这是自动生成的JS代码 <script>/*<![CDATA[*/function userTemplate(_$0,_$1,_$2){ _$1={}; for(_$2 in _$0){_$1[_$2]=_$0[_$2]}; _$0=_$1,_$1=[]; _$2=function(c){return "&#"+c.charCodeAt()+";";} with(_$0){ _$1.push("\t\t<h2>"); _$1.push(String(title).replace(/[<>&]/g,_$2)); _$1.push("</h2><table cellpadding=\"0\" cellspacing=\"0\">\t<tr>\t<th>姓名</th>\t<th>公司</th>\t<th>年龄</th>\t<th>城市</th>\t</tr>\t"); var _$3=data; var _$2=0; if(typeof _$3 == 'number'){ _$3= new Array(_$3); }else if(!(_$3 instanceof Array)){ var _$4= []; for(item in _$3){ _$4.push({key:item,value:_$3[item]}); } _$3=_$4; } for(;_$2<_$3.length;_$2++){ var item=_$3[_$2]; _$1.push("\t<tr>\t<td>"); _$1.push(String(item.name).replace(/[<>&]/g,_$2)); _$1.push("</td>\t<td>"); _$1.push(String(item.company).replace(/[<>&]/g,_$2)); _$1.push("</td>\t<td>"); _$1.push(String(item.age).replace(/[<>&]/g,_$2)); _$1.push("</td>\t<td>"); _$1.push(String(item.city).replace(/[<>&]/g,_$2)); _$1.push("</td>\t</tr>\t"); } _$1.push("\t</table>\t"); } return _$1.join(''); }/*]]>*/</script> [/list] |
|
返回顶楼 | |
发表时间:2009-04-07
zozoh 写道 呵呵,泼点冷水:
你这个想法和我几年前的想法不谋而合,总体的思路是:通过一层中间层,提供更简便灵活的视图书写方法。 但是现在回头来看,这种思路颇有隔靴搔痒的感觉,因为很难用 Firebug 直接 Debug 我写的代码,我最多能 Debug “你的通过我写的代码而生成的代码” 你的框架就是靴子,我再怎么样,都要隔着靴子去解决我的问题(找我的 Bug)。所以,在开发时,还不如直接写几个真正有用的 jQuery 的插件来的痛快。 但同时,是我也真心期望你的项目能够成功,因为你的成功就意味着你成功的改变了别人的使用习惯,能做到这一点很不简单。我现在设计的框架,基本上都本着“不改变或者尽量不改变用户的使用习惯”为原则的,起码,在这点上,你很用勇气,所以赞一个先,期待你的突破。 回来解释一下这些疑问吧。 [list] 半年前,那就那着LiteXML的早期版本做开发。压根就没有遇到调试需求。 设计这个模板的时候,有一个目标,那就是尽量不需要文档。 我们在开发过程中,没有做过任何相关培训,只有极少的关于语法的私下询问(貌似只有一次,当能,这也说明我们团队成员的水平还是非常不错的^_^) 可以看一下对比:模板源代码 <!-- 这里的内容会编译成JS函数(函数名userTemplate) --> <c:client id="userTemplate"> <h1>前后端统一模板实例</h1> <div id="content"> <h2>${title}</h2> <table cellspacing="0" cellpadding="0"> <tr> <th>姓名</th> <th>公司</th> <th>年龄</th> <th>城市</th> </tr> <c:for var="item" items="${data}"> <tr> <td>${item.name}</td> <td>${item.company}</td> <td>${item.age}</td> <td>${item.city}</td> </tr> </c:for> </table> </div> </c:client> 这是自动生成的JS代码 <script>/*<![CDATA[*/function userTemplate(_$0,_$1,_$2){ _$1={}; for(_$2 in _$0){_$1[_$2]=_$0[_$2]}; _$0=_$1,_$1=[]; _$2=function(c){return "&#"+c.charCodeAt()+";";} with(_$0){ _$1.push("\t\t<h2>"); _$1.push(String(title).replace(/[<>&]/g,_$2)); _$1.push("</h2><table cellpadding=\"0\" cellspacing=\"0\">\t<tr>\t<th>姓名</th>\t<th>公司</th>\t<th>年龄</th>\t<th>城市</th>\t</tr>\t"); var _$3=data; var _$2=0; if(typeof _$3 == 'number'){ _$3= new Array(_$3); }else if(!(_$3 instanceof Array)){ var _$4= []; for(item in _$3){ _$4.push({key:item,value:_$3[item]}); } _$3=_$4; } for(;_$2<_$3.length;_$2++){ var item=_$3[_$2]; _$1.push("\t<tr>\t<td>"); _$1.push(String(item.name).replace(/[<>&]/g,_$2)); _$1.push("</td>\t<td>"); _$1.push(String(item.company).replace(/[<>&]/g,_$2)); _$1.push("</td>\t<td>"); _$1.push(String(item.age).replace(/[<>&]/g,_$2)); _$1.push("</td>\t<td>"); _$1.push(String(item.city).replace(/[<>&]/g,_$2)); _$1.push("</td>\t</tr>\t"); } _$1.push("\t</table>\t"); } return _$1.join(''); }/*]]>*/</script> [/list] |
|
返回顶楼 | |
发表时间:2009-04-08
原来是这样啊,呵呵。 看来我理解错了,你说的没错,这里基本不包括复杂的逻辑,当然不太会出错。
如果 <c:client> 的就是把自己的 body 那些内容变成一个字符串返回的话,你为啥每次都拼接呢? 为啥不在 document onload 的时候放在一个全局的 object 里面,key 就是你的 client id, values 就是这段 innerHTML。 如果这个全局变量叫做 window.$patterns 我在使用的时候,直接调用 window.$patterns[modleId] 就能取得我要的 innerHTML,这样我在使用的时候,会更方便吧? |
|
返回顶楼 | |
发表时间:2009-04-08
zozoh 写道 原来是这样啊,呵呵。 看来我理解错了,你说的没错,这里基本不包括复杂的逻辑,当然不太会出错。
如果 <c:client> 的就是把自己的 body 那些内容变成一个字符串返回的话,你为啥每次都拼接呢? 为啥不在 document onload 的时候放在一个全局的 object 里面,key 就是你的 client id, values 就是这段 innerHTML。 如果这个全局变量叫做 window.$patterns 我在使用的时候,直接调用 window.$patterns[modleId] 就能取得我要的 innerHTML,这样我在使用的时候,会更方便吧? 呵呵,这个建议太技术人员了吧^_^。用户体验不要求性能的极限,只是要求性能问题不要让用户体验到。 在这种要求下,微乎其微的可能的性能提升远没有保持代码的简单优雅重要。 |
|
返回顶楼 | |
发表时间:2009-04-09
恩,这个不是关键,但是这个解决方案只能跑在 JSP 容器, 如果你用纯 JS 来作会不会更好。
因为你这个框架要作的事情就是替别人来缓存一组 HTML 字符串,一个不超过 50 行的 JS 文件就能全部搞定,而根本不用任何服务器端的代码才对。 |
|
返回顶楼 | |