`
jindw
  • 浏览: 501635 次
  • 性别: Icon_minigender_1
  • 来自: 初到北京
社区版块
存档分类
最新评论

决定在Lite XML中集成编译客户端模板功能

阅读更多

直接在服务断模板中划出一块做客户端模板

在模板编译过程中,会把<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>

 

 

 

 

 

 

分享到:
评论
21 楼 jiazhigang 2009-04-21  
xml早就有这个技术了,何必另起炉灶。
20 楼 jindw 2009-04-21  
nihongye 写道
编译成js函数,有什么用?


什么用处就在于自己去发掘了。呵呵
目前主要用在需要在前端组装ui的运用中,比如自定义首页那类。

当然也不都是那么极端,我觉得只要需要局部刷新的富客户端运用,都可以尝试。

数据模型也不一定非要服务端给,对于复杂的前端运用来说。
客户端完全应该有一个自己的数据模型,针对模型编程,而不是针对ui编程。
19 楼 nihongye 2009-04-21  
编译成js函数,有什么用?
18 楼 jindw 2009-04-13  
这就是沟通的误差,往往必须反复多次才能减少这种误差,呵呵。

zozoh 写道

引用
对于有工作经验的人,很容易犯先入为主的错误,我也经常犯类似错误,呵呵。
比如:
一提Java,就是JSP。

想问问,你的模板解析在什么时候做的呢? 在编译时,还是在运行时?

没错,实在编译时完成的,不过,这个编译过程可以在程序运行中第一次使用的时候编译。
java和js版本现在是自己编译,php版本可以通过java提供的编译服务远程编译,现在可以直接使用 http://litecompiler.appspot.com的编译服务。

zozoh 写道

引用
一看到xml,名称空间 就会想起jsp taglib。

你的 c: 看来是 client 的意思,哈哈,我说怎么和 jstl 重了呢

还是错了,c:不是 client的意思,我之所以取名c 确实是受jstl影响,不过我更愿意把它理解成condition,但是,现在加上 client之后,condition已经不止condition的意思了,还是叫core吧,呵呵

zozoh 写道

引用
一想起jsptaglib实现,就会认为他每次都会跑一遍。

taglib 是会和 jsp 代码一起变成 java 代码,在被编译成 class, 这个class 中你 taglib 变成的那段 java 调用每次请求都要走一遍,有什么错吗?

影响中jsp的taginf好像可以插入一些申明代码,我想可能也能插入一些静态内容吧,我也没怎么用过,不敢乱说。
不过我我在Lite中的编译是直接吧编译后的js静态插入到中间代码中的,也就是说,吧模板翻译成脚本的工作不会做第二次。


17 楼 zozoh 2009-04-10  
引用
其实也就是一些认识上的先入为主的误区。我上面讲的也不清楚,我罗列一下吧:
1.“jsp的请求”,“必须泡在JSP环境下”
这是一个跨平台的模板引擎,就算在Java环境上用,现在也没有支持jsp的tag,和jsp一点关系都扯不上。

咳,是这样的啊,的确理解错了。

引用
2.“每次对这个jsp的请求,你就会编译一遍”
为什么要这么做呢?这个猜测一定事拍屁股想出来的,^_^。

嗯,这个是我说错了。顺嘴就说了,呵呵。

引用

3.“你根本不输出 <c:client id="userListTemplate "> 这段内容”
其实,上面贴出的例子中也完全可以看出来,这里并没有这种内容的输出(可能我理解错了)。

看来你没明白我的意思是说,根本不输出 <c:client id="userListTemplate "> 编译后的 javascript 内容

引用
对于有工作经验的人,很容易犯先入为主的错误,我也经常犯类似错误,呵呵。
比如:
一提Java,就是JSP。

想问问,你的模板解析在什么时候做的呢? 在编译时,还是在运行时?

引用
一看到xml,名称空间 就会想起jsp taglib。

你的 c: 看来是 client 的意思,哈哈,我说怎么和 jstl 重了呢

引用
一想起jsptaglib实现,就会认为他每次都会跑一遍。

taglib 是会和 jsp 代码一起变成 java 代码,在被编译成 class, 这个class 中你 taglib 变成的那段 java 调用每次请求都要走一遍,有什么错吗?

引用
一想到模板,他一定在服务端运行。前端XHR请求数据
一想起前端模板,他一定要在前端解析。

这个我就不好说什么了,呵呵
16 楼 jindw 2009-04-10  
其实也就是一些认识上的先入为主的误区。我上面讲的也不清楚,我罗列一下吧:

1.“jsp的请求”,“必须泡在JSP环境下”
这是一个跨平台的模板引擎,就算在Java环境上用,现在也没有支持jsp的tag,和jsp一点关系都扯不上。

2.“每次对这个jsp的请求,你就会编译一遍”
为什么要这么做呢?这个猜测一定事拍屁股想出来的,^_^。

3.“你根本不输出 <c:client id="userListTemplate "> 这段内容”
其实,上面贴出的例子中也完全可以看出来,这里并没有这种内容的输出(可能我理解错了)。

对于有工作经验的人,很容易犯先入为主的错误,我也经常犯类似错误,呵呵。
比如:
一提Java,就是JSP。
一看到xml,名称空间 就会想起jsp taglib。
一想起jsptaglib实现,就会认为他每次都会跑一遍。
一想到模板,他一定在服务端运行。前端XHR请求数据
一想起前端模板,他一定要在前端解析。





avidmouse 写道
jindw 写道
zozoh 写道
你实际上是把HTML模板,变成一个 JS 函数,这个函数返回的是字符串。 每次对这个jsp的请求,你就会编译一遍。

我的想法大概是这样的:
当用户请求你的网页的时候,你根本不输出 <c:client id="userListTemplate "> 这段内容,
如果当用户调用 userListTemplate(userList)  你就向服务器发请求,请求一个叫 userList 的模板,拿下来,存在 window 对象上,下次再叫 userListTemplate(userList)的时候,你就直接返回给它。
就写作这么一小段 JS 就足够了。

至于服务器端,可以用php,asp,ruby,java 随便什么都无所谓。



恕我直言,你的理解很多是错的。

很多是错的,很多指什么?没有申明这个变量吧?

15 楼 avidmouse 2009-04-10  
jindw 写道
zozoh 写道
你实际上是把HTML模板,变成一个 JS 函数,这个函数返回的是字符串。 每次对这个jsp的请求,你就会编译一遍。

我的想法大概是这样的:
当用户请求你的网页的时候,你根本不输出 <c:client id="userListTemplate "> 这段内容,
如果当用户调用 userListTemplate(userList)  你就向服务器发请求,请求一个叫 userList 的模板,拿下来,存在 window 对象上,下次再叫 userListTemplate(userList)的时候,你就直接返回给它。
就写作这么一小段 JS 就足够了。

至于服务器端,可以用php,asp,ruby,java 随便什么都无所谓。



恕我直言,你的理解很多是错的。

很多是错的,很多指什么?没有申明这个变量吧?
14 楼 jindw 2009-04-10  
zozoh 写道
你实际上是把HTML模板,变成一个 JS 函数,这个函数返回的是字符串。 每次对这个jsp的请求,你就会编译一遍。

我的想法大概是这样的:
当用户请求你的网页的时候,你根本不输出 <c:client id="userListTemplate "> 这段内容,
如果当用户调用 userListTemplate(userList)  你就向服务器发请求,请求一个叫 userList 的模板,拿下来,存在 window 对象上,下次再叫 userListTemplate(userList)的时候,你就直接返回给它。
就写作这么一小段 JS 就足够了。

至于服务器端,可以用php,asp,ruby,java 随便什么都无所谓。



恕我直言,你的理解很多是错的。
13 楼 Bernard 2009-04-09  
没有能把异常源码行抛出所需的信息么?
我现在也很头疼这个问题。
编译时检查行肯定没问题,可在生产过程出要抛出错误相关行就必须记录住源码行或者按照一定的特征信息重新扫描模版源文件。
其实给出错误区块描述也可以。

呃~~你不是不喜欢xslt么~~我看这个怎么越写越像xslt。

还有一种修饰性模版操作方法,非常直观,侵入性很小。
和这主题关系不是很大,但在写Js时比较常用,可以参考一下。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
    jQuery(document).ready(function(){
        var data = [
            {title:"title_1"},
            {title:"title_2"},
            {title:"title_3"},
            {title:"title_4"},
            {title:"title_5"}
        ];
        var ex = jQuery("._example");
        var el = null;
        for(var i = data.length - 1;i >= 0;i--){
            el = ex.clone();
            el.removeClass("_example");
            el.html((el.html() || "").replace("{$title}",data[i].title));
            ex.after(el);
        }
        ex.remove();
    });
</script>


<ul>
    <li class="myli _example">{$title}</li>
</ul>
12 楼 whaosoft 2009-04-09  
这个比v和f 那俩个好用吗??
11 楼 zozoh 2009-04-09  
你实际上是把HTML模板,变成一个 JS 函数,这个函数返回的是字符串。 每次对这个jsp的请求,你就会编译一遍。

我的想法大概是这样的:
当用户请求你的网页的时候,你根本不输出 <c:client id="userListTemplate "> 这段内容,
如果当用户调用 userListTemplate(userList)  你就向服务器发请求,请求一个叫 userList 的模板,拿下来,存在 window 对象上,下次再叫 userListTemplate(userList)的时候,你就直接返回给它。
就写作这么一小段 JS 就足够了。

至于服务器端,可以用php,asp,ruby,java 随便什么都无所谓。

10 楼 jindw 2009-04-09  
zozoh 写道
恩,这个不是关键,但是这个解决方案只能跑在 JSP 容器, 如果你用纯 JS 来作会不会更好。
因为你这个框架要作的事情就是替别人来缓存一组 HTML 字符串,一个不超过 50 行的 JS 文件就能全部搞定,而根本不用任何服务器端的代码才对。



我想你理解错了。我为什么要在服务端做?
因为我需要在模板编译环节做脚本的前端模板的编译,只要一次。

因为如果不这样做,模板的解析放在客户端,每次都要解析一遍,开销算谁的。
仍外,这个貌似50行代码是做不了这个事情的,至少我没有这本事。呵呵
9 楼 zozoh 2009-04-09  
恩,这个不是关键,但是这个解决方案只能跑在 JSP 容器, 如果你用纯 JS 来作会不会更好。
因为你这个框架要作的事情就是替别人来缓存一组 HTML 字符串,一个不超过 50 行的 JS 文件就能全部搞定,而根本不用任何服务器端的代码才对。
8 楼 jindw 2009-04-08  
zozoh 写道
原来是这样啊,呵呵。 看来我理解错了,你说的没错,这里基本不包括复杂的逻辑,当然不太会出错。

如果 <c:client> 的就是把自己的 body 那些内容变成一个字符串返回的话,你为啥每次都拼接呢? 为啥不在 document onload 的时候放在一个全局的 object 里面,key 就是你的 client id, values 就是这段 innerHTML。 如果这个全局变量叫做 window.$patterns  我在使用的时候,直接调用 window.$patterns[modleId]
就能取得我要的 innerHTML,这样我在使用的时候,会更方便吧?


呵呵,这个建议太技术人员了吧^_^。用户体验不要求性能的极限,只是要求性能问题不要让用户体验到。
在这种要求下,微乎其微的可能的性能提升远没有保持代码的简单优雅重要。
7 楼 zozoh 2009-04-08  
原来是这样啊,呵呵。 看来我理解错了,你说的没错,这里基本不包括复杂的逻辑,当然不太会出错。

如果 <c:client> 的就是把自己的 body 那些内容变成一个字符串返回的话,你为啥每次都拼接呢? 为啥不在 document onload 的时候放在一个全局的 object 里面,key 就是你的 client id, values 就是这段 innerHTML。 如果这个全局变量叫做 window.$patterns  我在使用的时候,直接调用 window.$patterns[modleId]
就能取得我要的 innerHTML,这样我在使用的时候,会更方便吧?
6 楼 jindw 2009-04-07  
zozoh 写道
呵呵,泼点冷水:

你这个想法和我几年前的想法不谋而合,总体的思路是:通过一层中间层,提供更简便灵活的视图书写方法。
但是现在回头来看,这种思路颇有隔靴搔痒的感觉,因为很难用 Firebug 直接 Debug 我写的代码,我最多能 Debug “你的通过我写的代码而生成的代码” 你的框架就是靴子,我再怎么样,都要隔着靴子去解决我的问题(找我的 Bug)。所以,在开发时,还不如直接写几个真正有用的 jQuery 的插件来的痛快。

但同时,是我也真心期望你的项目能够成功,因为你的成功就意味着你成功的改变了别人的使用习惯,能做到这一点很不简单。我现在设计的框架,基本上都本着“不改变或者尽量不改变用户的使用习惯”为原则的,起码,在这点上,你很用勇气,所以赞一个先,期待你的突破。



回来解释一下这些疑问吧。


[list]
 
  • 语法错误让编译器解决。
  •   如果你模板中表达式本身有错,那么,你的编译器就会报告给你。
     
  • 不应该有太多调试的需求
  •   保持模板简单的原则,如果你的模板需要调试,那我可以认为你的模板设计的不好。
      半年前,那就那着LiteXML的早期版本做开发。压根就没有遇到调试需求。
      设计这个模板的时候,有一个目标,那就是尽量不需要文档。
      我们在开发过程中,没有做过任何相关培训,只有极少的关于语法的私下询问(貌似只有一次,当能,这也说明我们团队成员的水平还是非常不错的^_^)
     
  • 就算有调试需求,那就打开Firebug去Debug
  •   模板处理的逻辑是简单的,生成的代码结构也就是简单的。
      可以看一下对比:模板源代码
        <!-- 这里的内容会编译成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]



    5 楼 jindw 2009-04-07  
    zozoh 写道
    呵呵,泼点冷水:

    你这个想法和我几年前的想法不谋而合,总体的思路是:通过一层中间层,提供更简便灵活的视图书写方法。
    但是现在回头来看,这种思路颇有隔靴搔痒的感觉,因为很难用 Firebug 直接 Debug 我写的代码,我最多能 Debug “你的通过我写的代码而生成的代码” 你的框架就是靴子,我再怎么样,都要隔着靴子去解决我的问题(找我的 Bug)。所以,在开发时,还不如直接写几个真正有用的 jQuery 的插件来的痛快。

    但同时,是我也真心期望你的项目能够成功,因为你的成功就意味着你成功的改变了别人的使用习惯,能做到这一点很不简单。我现在设计的框架,基本上都本着“不改变或者尽量不改变用户的使用习惯”为原则的,起码,在这点上,你很用勇气,所以赞一个先,期待你的突破。



    回来解释一下这些疑问吧。


    [list]
     
  • 语法错误让编译器解决。
  •   如果你模板中表达式本身有错,那么,你的编译器就会报告给你。
     
  • 不应该有太多调试的需求
  •   保持模板简单的原则,如果你的模板需要调试,那我可以认为你的模板设计的不好。
      半年前,那就那着LiteXML的早期版本做开发。压根就没有遇到调试需求。
      设计这个模板的时候,有一个目标,那就是尽量不需要文档。
      我们在开发过程中,没有做过任何相关培训,只有极少的关于语法的私下询问(貌似只有一次,当能,这也说明我们团队成员的水平还是非常不错的^_^)
     
  • 就算有调试需求,那就打开Firebug去Debug
  •   模板处理的逻辑是简单的,生成的代码结构也就是简单的。
      可以看一下对比:模板源代码
        <!-- 这里的内容会编译成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]
    4 楼 jindw 2009-04-07  
    zozoh 写道
    呵呵,泼点冷水:

    你这个想法和我几年前的想法不谋而合,总体的思路是:通过一层中间层,提供更简便灵活的视图书写方法。
    但是现在回头来看,这种思路颇有隔靴搔痒的感觉,因为很难用 Firebug 直接 Debug 我写的代码,我最多能 Debug “你的通过我写的代码而生成的代码” 你的框架就是靴子,我再怎么样,都要隔着靴子去解决我的问题(找我的 Bug)。所以,在开发时,还不如直接写几个真正有用的 jQuery 的插件来的痛快。

    但同时,是我也真心期望你的项目能够成功,因为你的成功就意味着你成功的改变了别人的使用习惯,能做到这一点很不简单。我现在设计的框架,基本上都本着“不改变或者尽量不改变用户的使用习惯”为原则的,起码,在这点上,你很用勇气,所以赞一个先,期待你的突破。


    太晚了,明天再来答复你的疑问吧,先概括一下:
    你的担心不是没有道理,但是根据以往经验。我们没有碰到,也许基于Lite的实现就很难碰到。
    3 楼 jindw 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>
    
    
    2 楼 zozoh 2009-04-06  
    呵呵,泼点冷水:

    你这个想法和我几年前的想法不谋而合,总体的思路是:通过一层中间层,提供更简便灵活的视图书写方法。
    但是现在回头来看,这种思路颇有隔靴搔痒的感觉,因为很难用 Firebug 直接 Debug 我写的代码,我最多能 Debug “你的通过我写的代码而生成的代码” 你的框架就是靴子,我再怎么样,都要隔着靴子去解决我的问题(找我的 Bug)。所以,在开发时,还不如直接写几个真正有用的 jQuery 的插件来的痛快。

    但同时,是我也真心期望你的项目能够成功,因为你的成功就意味着你成功的改变了别人的使用习惯,能做到这一点很不简单。我现在设计的框架,基本上都本着“不改变或者尽量不改变用户的使用习惯”为原则的,起码,在这点上,你很用勇气,所以赞一个先,期待你的突破。

    相关推荐

    Global site tag (gtag.js) - Google Analytics