<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>sp42</title>
    <description>极爱JAVA及其SCRIPT</description>
    <link>http://sp42.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>发布Ext中文文档：在线版与AIR绿色打包版alpha 0.1</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/216574" style="color:red;">http://sp42.javaeye.com/blog/216574</a>&nbsp;
          发表时间: 2008年07月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我们相信，开源如果没有良好的文档支持，创意再好，技术再先进的项目，也不会获得很大的成功。80后的中国人重理轻文，这种现象在软件行业也普遍存在。最直接的后果是，世界上很多很优秀的项目，由于缺乏良好的汉化文档支持，无人问津。本汉化文档的宗旨在于给ExtJS的中国用户多一些的文档支持，并且尽我们之能力提供相关咨询解答。<br /><br />关于ExtJS有不少争论，尤其是当把它和Dojo比较的时候，很多人会埋怨它加载的JS包文件太大。但正如C++之父 Bjarne Stroustrup 所说的，"世界上只有两种语言：一种是每个人都在抱怨的，一种是没有人用的。"埋怨也不全是坏事，至少有很多人在用，我们才会听到埋怨的声音。Dojo是个构建平台优秀的工具，尤其在全面要求Dhtml/Ajax开发，它异常强大。但是Ext关注的不仅仅是Ajax应用平台，它更是个HTML/CSS/JS为基础的最佳实践，除了构建UI元素，还能用以扩展自己的组件，以及复杂的排版布局。再者，当项目变得庞大的时候，遵循YUI/ExtJS（YUI/Ext一脉相承）的面向对象开发体系（OO Architecture）能帮你书写更清晰、可维护的代码。诚然，Ext的配置项略显复杂，按需加载也没有Dojo那么好，但在该领域没有出现更优秀的工具前，ExtJS还是您的首选。<br /><br />事实上Ext不仅仅是一个Ajax工具包，它更是一种先进的UI组件制作理念，其一是基于Java Swing的对象模型，只要你熟悉Swing，你可以节省很多时间，这一理念可以在Ext.Container/Layout中看到。其二是组件对象的统一模型，包括组件的创建、渲染、事件处理、状态管理和销毁这些框架Ext已经帮你定义好了，你只要稍作修改便能符合你的要求。<br /><br />如何尽量避免使用Ext可能遇到的问题，如何运用Ext的一些最佳实践，这是很多Ext用户最想知道的，在此，我们会提供力所能及的帮助。<br /><br />中国有大量的Ext用户，在更多人的努力下，我坚信这个队伍会不断壮大。<br /><br /><strong>预览：</strong> <a href="http://www.ajaxjs.com/docs/" target="_blank">http://www.ajaxjs.com/docs/</a><br /><strong>AIR版文档中心下载：</strong> <a href="http://www.ajaxjs.com/docs/Ext 2 API Documentation.zip" target="_blank">http://www.ajaxjs.com/docs/Ext 2 API Documentation.zip</a> ~3MB<br />要求：Adobe AIR虚拟机 v1.1或以上 <br />用法：直接打开2.1 API Documentation.exe<br /><br /><strong>完整任务进度表（包括了我们翻译小组的人员名单）：</strong><br /><a href="http://chineseext.googlecode.com/svn/trunk/list.htm" target="_blank"><img src="http://www.ajaxjs.com/docs/ad.gif" /></a><br /><a href="http://chineseext.googlecode.com/svn/trunk/list.htm" target="_blank">http://chineseext.googlecode.com/svn/trunk/list.htm</a>(取自SVN，需“另存为”后查看)<br /><br /><strong>log：</strong><br />1.此版本为公开测试版alpha 0.1 把我们当前已完成汉化的公开；<br />2.汉化工作持续进行中，有兴趣的朋友，不要犹豫了，<a href="http://jstang.5d6d.com/thread-90-1-2.html" target="_blank">加入我们翻译小组</a>；<br />3.版权协议为Creative Commons 署名-非商业性使用 2.5<br /><a href="http://jstang.5d6d.com/thread-90-1-2.html" target="_blank"><img src="http://www.ajaxjs.com/docs/banner_3.gif" /></a>
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/216574#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 19 Jul 2008 21:03:47 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/216574</link>
        <guid>http://sp42.javaeye.com/blog/216574</guid>
      </item>
      <item>
        <title>ExtJS与RESTful Web Services</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/216489" style="color:red;">http://sp42.javaeye.com/blog/216489</a>&nbsp;
          发表时间: 2008年07月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>重要消息：按照Ext <a href="http://extjs.com/roadmap" title="http://extjs.com/roadmap" class="external text" rel="nofollow">Roadmap</a>
的规划， Ext 2.1（2008春天）已经完整支持REST了！不错的消息！
</p>
<table class="toc" border="0" id="toc" summary="目錄" width="3" style="height: 1px;">
<tbody>
<tr>
<td></td>
</tr>
</tbody>
</table>
<h1><span class="mw-headline">REST与RESTful Web Services </span>
</h1>
<p>表述性状态传送（<strong>REST</strong>
）是一种架构上的风格。此术语由<a href="http://www.ics.uci.edu/%7Efielding/" title="http://www.ics.uci.edu/~fielding/" class="external text" rel="nofollow">Roy Fielding</a>
（联合制定 HTTP标准联合作者之一）所创造。在<a href="http://www.ics.uci.edu/%7Efielding/pubs/dissertation/rest_arch_style.htm" title="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" class="external text" rel="nofollow">他的博士论文的第五章中</a>
， 焦点的内容是关于<em>现代Web架构的设计底层原理和与其他架构风格所不同的地方</em>
。
</p>
<p>对于REST粗浅的理解可以这样地形容:你拥有<strong>一些资源（Resources）</strong>
（概念化一些对象，就像数据库中实体）， 资源统一经由某些接口所暴露出来（web之上便是<strong>HTTP协议</strong>
和五个常用的标准HTTP动词：<strong>GET</strong>
、<strong>POST</strong>
、<strong>PUT</strong>
、<strong>DELETE</strong>
和<strong>OPTIONS</strong>
）。 资源的状态<strong>表述（Representations）</strong>
经统一的接口访问和操作。比如，要查看用户的账号你就要GET账号的状态表述，要更新它就要PUT一次新的表述，要移除它就要DELETE资源等等...
</p>
<p>REST并不限制应用于HTTP上（HTTP一种基于消息的协议，驱动着整个互联网），而且纯技术而言，为实现REST风格，你的统一接口
不一定要使用以上五个动词，也可达到真的&ldquo;RESTful&rdquo;。但目前大多数基于WEB的&ldquo;RESTful&rdquo;服务（web-based services）<strong>却是</strong>
构建于采用这五个标准动词的HTTP协议，因此我们会着重关心。
</p>
<p>我深受REST的影响缘起于Leonard Richardson和Sam Ruby有关该主题的权威书籍（07年期间）<a href="http://www.amazon.com/RESTful-Web-Services-Leonard-Richardson/dp/0596529260" title="http://www.amazon.com/RESTful-Web-Services-Leonard-Richardson/dp/0596529260" class="external text" rel="nofollow">RESTful Web Services</a>
（O'Reilly
出版）。欲对REST了解更深的话我就强烈推荐你阅读这本书。为不偏离本文主旨，我不打算讨论REST的理论和解释为什么要采用RESTful风格的
Web Services（总之本文的侧重点不在这里），所以，笔者这里假设在下已经权衡分析REST的利、弊并作出决定投身REST的革命中:)
</p>
<p>
<a name="A_Disclaimer_of_Sorts"></a>
</p>
<h2><span class="mw-headline">A Disclaimer of Sorts </span>
</h2>
<p>无论是ExtJS还是其他Ajax库，凡涉及RESTful Web
Services之处并非神秘不可测，终究我们所研究的REST只是在利用HTTP协议通讯下的，一组最佳实践而已。好的消息是，在主流浏览器中，让
Ajax成为可能的XmlHttpRequest对象均可完整地支持五种标准的HTTP动词。坏消息是几乎是所有的WEB开发者到最近才意识到REST的
重要性，这样就导致了大多数的Ajax的库、框架到现在还是认为你只会发起GET
或POST的请求。有鉴于此，你就必须了解AJAX库的底层是怎么样的，去操作PUT/DELETE/OPTIONS的请求。总之，本文可被看做是进一步
挖掘ExtJS API的教程，竭尽全力使你懂得API的原理（借此能对非REST的ExtJS用户有所帮助）。 </p>
<p>
<a name="HTTP.E6.96.B9.E6.B3.95"></a>
</p>
<h2><span class="mw-headline">HTTP方法</span>
</h2>
<p>当需要在Ajax请求中指定某个HTTP方法是不太困难的，尤其在使用底层方法Ext.Ajax.request()方法的时候。由于我们多数是在
较高级的API下工作的（像配置Ext.grid.GridPanel中的Ext.data.Store），所以接触Ext.Ajax.request方
法的机会比较小，但并不说明在调用这种级别的API是麻烦的，相反这是很方便地让你控制Ext发出各种请求（当调试RESTful
Web服务时，能更方便地直接生成这些请求，&mdash;&mdash;不过你可能发现基于命令行的curl库会更为方便）。
</p>
<p>以下是一些例子（使用Firebug的控制台来了解例子运行的状况并实时观察XHR正在发出的请求）。
</p>
<p>从/users资源处获取（GET）列表：
</p>
<pre>Ext.Ajax.request({
 url: '/users',
 method: 'GET'
})
</pre>
<p>POST（提交）一篇新的文章到/articles资源：
</p>
<pre>Ext.Ajax.request({
 url: '/articles',
 method: 'POST',
 params: {
  author: 'Patrick Donelan',
  subject: 'RESTful Web Services'
 }
})
</pre>
<p>在/articles/restful-web-services 资源处，对文章PUT（执行）一次representation（表征式）的更新：
</p>
<pre>Ext.Ajax.request({
 url: '/articles/restful-web-services',
 method: 'PUT',
 params: {
  author: 'Patrick Donelan',
  subject: 'RESTful Web Services are easy with Ext!'
 }
})
</pre>
<p>DELETE（删除）位于/articles/rpc-is-the-best-web-architecture的资源：
</p>
<pre>Ext.Ajax.request({
 url: '/articles/rpc-is-the-best-web-architecture',
 method: 'DELETE',
 success: function(){ alert('Begone!'); }
})
</pre>
<p>
<a name="HTTP.E7.8A.B6.E6.80.81.E4.BB.A3.E7.A0.81"></a>
</p>
<h2><span class="mw-headline">HTTP状态代码</span>
</h2>
<p>HTTP规范中定义了<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" title="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" class="external text" rel="nofollow">许多状态代码（Status Codes）</a>
，用于代码表示HTTP传输过程是怎样的。下面都一些你熟悉的代码：
</p>
<ul>
<li> '404 Not Found' - 找不到请求的资源
</li>
<li> '401 Unauthorized' - 请求需要用户认证
</li>
<li> '200 OK' - 请求发生成功
</li>
</ul>
<p>也有可能是：
</p>
<ul>
<li> '500 Internal Server Error' - 服务器发生错误
</li>
<li> '503 Service Unavailable' - web服务器有可能超负荷了
</li>
</ul>
<p>如果你对过去五年的WEB开发有所了解，你会发现为什么仅仅有这些Status
Codes是情有可原的。话又说回来，HTML文件构成的静态站点只会让你遇到以上的status
code。而由编程语言（如Perl、PHP、Ruby、Java等）动态生成的站点，你可能遇到其他更多的Status Codes。
</p>
<p>综合来说：HTTP status codes（都是三位数字）可归纳为:
</p>
<ul>
<li> 1xx - 信息 Informational（可能与你无关）
</li>
<li> 2xx - 成功 Success（例如'200 OK'和'201 Created'）
</li>
<li> 3xx - 转向 Redirection
</li>
<li> 4xx - 客户端错误 Client Error（例如一般的&ldquo;400 Bas Request&rdquo;）
</li>
<li> 5xx - 服务端错误 Server Error （例如&ldquo;500 Internal Server Error&rdquo;）
</li>
</ul>
<p><br />
有人会问，有必要这么详细的分类吗？当然有，不过为了不涉及其他过多的话题我假设你懂得原因（参见文章底部的<a href="http://extjs.com/learn/Manual:RESTful_Web_Services_%28Chinese%29#.E5.BB.B6.E4.BC.B8.E9.98.85.E8.AF.BB">#延伸阅读</a>
）部分以了解更多的内容）。
</p>
<p>使用HTTP状态代码的一个很好的理由就是（另外一个是因为我们是JavaScript的开发者）可以让我们无须理会请求的内容是什么、返回的Response的具体又是什么就可以处理分析这次的Response成功操作与否。
</p>
<p>例如，脚本无须了解响应的消息体（response body）的格式究竟是什么就可得知请求成功与否（4xx有可能验证错误，2xx操作成功，5xx服务器不能工作）。
</p>
<p><br />
 
你完全可以在你的脚本中构建一个清晰而合理的方式与服务端通讯，而且你会越来越感觉与HTTP系统打交道是一个非常自然的事情（例如你脚本中有错误了那么服务端就可能反馈你一个5xx的状态代码）。
</p>
<p><br />
另外重要的一方面是，你会发现不需要将状态信息放到整个body身上，这样对于你(one less non-standard
thing to document)
和其他使用你Web服务的人都带来了方便，因为在统一的接口界面下（interface）他们能够利用现有的知识而不需要再学习你的语法。
</p>
<p>牵涉一个相关的例子，例如，Ext API其中一部分我觉得要强调的是（尽管这里表达是良性的批评-见<a href="http://extjs.com/learn/Manual:RESTful_Web_Services_%28Chinese%29#A_Disclaimer_of_Sorts">#A Disclaimer of Sorts</a>
），<a href="http://extjs.com/learn/Manual:Forms:Result_Format" title="http://extjs.com/learn/Manual:Forms:Result_Format" class="external text" rel="nofollow">在服务端的响应中，BasicForm与Form的actions应接收某些特定的Ext参数</a>
，以便正确自动地作出表单验证和回调函数success/failure的处理。
</p>
<p><br />
例如，一次成功的请求应该会返回'200 OK'和下面的实体（尤其注意&quot;success&quot;属性）：
</p>
<pre>{
 &quot;success&quot;: true,
 &quot;data&quot;: {
  &quot;field_id_1&quot;: &quot;Field 1 Value&quot;,
  &quot;field_id_2&quot;: &quot;Field 2 Value&quot;
 }
}
</pre>
<p>实体好像是多余的，因为你会觉得200的状态代码是代表成功的。
</p>
<p>另外，即使请求不获验证的通过，也是返回'200 OK'（不返回4XX的代码，那样的意思是请求包含客户端无效的数据），实体会是这样的：
</p>
<pre>{
 &quot;success&quot;: false,
 &quot;errors&quot;: [
  { &quot;id&quot;: &quot;field_id_1&quot;, &quot;msg&quot;: &quot;Field 1 Error Message&quot; },
  { &quot;id&quot;: &quot;field_id_2&quot;, &quot;msg&quot;: &quot;Field 2 Error Message&quot; }
 ]
}
</pre>
<p>当中最大的问题是，如果你只是想提交表单，却在JSON/xml实体body中忘记包含Ext指定的属性&quot;success: true&quot;就会返回一个成功的status code但是空内容的body：
</p>
<pre>{
}
</pre>
<p>即是服务端告诉你这是一个成功的请求，form所属的提交的handler却不会执行相应的回调函数！
这样会使得不熟悉ExtJS的程序员狂抓（或者像我这样的人有时会忘记强制性的&ldquo;success&rdquo;属性），为什么Ext会忽略那些状态代码。
</p>
<p><br />
总之，回到务实的态度上，你可以用Ext.form.BasicForm或Ext.form.Form提交Aajx表单，而不需要
在实体上指定Ext特有的success属性，仍然可以提交如执行Ext.Ajax.request()时相类似，参数做了有关http状态码与回调
success/failure的方面的事情：
</p>
<pre>Ext.Ajax.request({
 url: '/some_resource',
 method: 'POST',
 form: 'my-form-id',
 success: function(){alert('Must have been 2xx http status code')},
 failure: function(){alert('Must have been 4xx or a 5xx http status code')},
});
</pre>
<p>这意味着验证错误的信息将不能自动显示（却是一个好的功能）你可以在Ex底层代码中轻松地分离这一块的功能，若你遭遇到4xx的代码就直接调用该方
法。下面我就我组件项目中的实际需求贴出来给大家看看，我先没有使用Ext.form.BasicForm因为我希望实现Http状态码感知（HTTP
Status Code aware）！
</p>
<p>
<a name="Busting_the_Cache-buster"></a>
</p>
<h2><span class="mw-headline">Busting the Cache-buster </span>
</h2>
<p>使用REST其中一个好处是，你会与HTTP<strong>一起</strong>
工作而不是排斥它（又来RPC?!）比如，你很可能会依靠HTTP
headers来控制内容的有效期和缓存。默认下，为每次得到刷新内容，Ext会在每次的GET中加入一个特别的&ldquo;cache-buster&rdquo;参数。要禁
用这项功能，你可以在javascript代码中加入这一行(which those fond of double-negatives will
especially enjoy)：
</p>
<pre>Ext.Ajax.disableCaching = false;
</pre>
<p>
<a name=".E8.A1.A8.E8.BF.B0.E5.BC.8F.E7.9A.84.E8.B5.84.E6.BA.90.EF.BC.8C.E6.96.87.E6.A1.A3.E7.B1.BB.E5.9E.8B.EF.BC.88Content_Types.EF.BC.89.E5.92.8CAccept:_header"></a>
</p>
<h2><span class="mw-headline">表述式的资源，文档类型（Content Types）和Accept: header </span>
</h2>
<p>假设我们有一处表述式的资源位于 <a href="http://server.com/resource" title="http://server.com/resource" class="external free" rel="nofollow">http://server.com/resource</a>
 你打算用GET方法获取它。
一些RESTful Web Service会根据你请求中HTTP头部&quot;Accept:&quot;字段以决定返回序列化的格式。
比如，请求是这样的：
</p>
<pre>GET /resource HTTP/1.1
Host: server.com
Accept: application/json
</pre>
<p>这是服务端会返回（JSON格式）：
</p>
<pre>[ 
 {a:1, b:2},
 {a:3, b:4}
]
</pre>
<p>若你的请求是这样的：
</p>
<pre>GET /resource HTTP/1.1
Host: server.com
Accept: */*
</pre>
<p>服务端就会返回默认的格式，如XML:
</p>
<pre>&lt;opt&gt;
 &lt;data a=&quot;1&quot; b=&quot;2&quot; /&gt;
 &lt;data a=&quot;3&quot; b=&quot;4&quot; /&gt;
&lt;/opt&gt;
</pre>
<p>Ext中的一个常见的场景是，在获取所有的表述内容的都固定某种的格式（很可能是JSON）,最快的方法是在每个请求中设置一个缺省的头部（&quot;Accept:&quot; header）：
</p>
<pre>Ext.Ajax.defaultHeaders = {
 'Accept': 'application/json'
};
</pre>
<p>之后发生的所有请求将把&quot;Accept:&quot;的头部内容设置为&quot;application/json&quot;。 例如，我们发起一次GET的请求到/resource并观察Firebug 检查发出的headers：
</p>
<pre>Ext.Ajax.request({
 url: '/resource',
 params: {
  test: 1
 },
 method: 'GET'
})
</pre>
<p>得到：
</p>
<pre>Host: server.com
Accept: application/json
X-Requested-With: XMLHttpRequest
..
</pre>
<p>
<a name="Data_Stores.EF.BC.8C.E8.87.AA.E5.AE.9A.E4.B9.89HTTP_Methods.EF.BC.88HTTP.E6.96.B9.E6.B3.95.EF.BC.89.E5.92.8CExt.data.JsonStore.E7.9A.84.E5.AE.9E.E8.B7.B5.E4.BE.8B.E5.AD.90"></a>
</p>
<h2><span class="mw-headline">Data Stores，自定义HTTP Methods（HTTP方法）和Ext.data.JsonStore的实践例子 </span>
</h2>
<p>Ext具备清晰而完整对象层次。一个例子便是Ext.data.Store把Record对象&ldquo;封装&rdquo;为客户端缓存，用于某些组件，如
GridPanel、ComboBox或DataView提取数据。下面会讲到用 Ext.data.JsonStore类动态生成
Ext.form.ComboBox组件，假设有一个Web Service，能够返回JSON格式的资源：
</p>
<pre>var cb = new Ext.form.ComboBox({
 store: new Ext.data.JsonStore({
  url: '/resource?query=something',
  fields: ['id']
  }),
 displayField: 'id',
 valueField: 'id',
 triggerAction: 'all',
 renderTo: document.body
})

</pre>
<p>要留意查询的参数那里（通常给人第一的感觉这应该是GET的请求），在EXT中实际还是使用了POST的方法获取数据！
</p>
<p>如果我们就这样发送到一个RESTful的Web Service，你很可能就会发现返回的是&ldquo;405 -Not Implemented&rdquo;的HTTP状态码（假设资源仅支持GET）。
即使你的面对的不是一个RESTfule的Web Service，只要你的服务端语言能够分辨GET或POST的参数的话，你仍有机会使用GET，让服务器能够读取请求的参数。
</p>
<p>Ext.data.JsonStore实际上来说是混合了Ext.data.Proxy与Ext.data.Reader的一个强大的
Ext.data.Store类，减少了不必要的对象耦合。不过接下来我们不使用Ext.data.JsonStore而是重新定义我们的
Ext.data.JsonStore,这是增加了几行代码但能更好地说明问题。
如果你经常使用这个store你可以重新定义个Ext.data.MorePowerfulJsonStore对象，将多个对象封装在内（instead
of hard-wiring things）：
</p>
<p>&nbsp;</p>
<pre>var cb = new Ext.form.ComboBox({
 store: new Ext.data.Store({
  proxy: new Ext.data.HttpProxy({
   url: '/resource',
   method: 'GET',
   params: {
 	query: 'something'
   }
  }),
  reader: new Ext.data.JsonReader({
   fields: ['id']
  })
 }),
 displayField: 'id',
 valueField: 'id',
 triggerAction: 'all',
 renderTo: document.body
})
</pre>
<p>正如所见，通过定义Ext.data.HttpProxy可允许你指定任意一种HTTP方法。因此除了你习惯的GET方法获取Data Store对象，还可以使用其他任意你喜欢的HTTP方法。
</p>
<p>
<a name="HTTP.E8.AE.A4.E8.AF.81.EF.BC.88Authentication.EF.BC.89"></a>
</p>
<h2><span class="mw-headline"> HTTP认证（Authentication） </span>
</h2>
<p>HTTP协议中相关的认证头部，都是可扩展和定义良好的字段，依靠这些字段来完成HTTP的认证机制（HTTP Authention scheme），是基于RESTful风格的Web Services的常见做法。实现的例子有<a href="http://en.wikipedia.org/wiki/Basic_access_authentication" title="http://en.wikipedia.org/wiki/Basic_access_authentication" class="external text" rel="nofollow">HTTP Basic Authentication</a>
、<a href="http://en.wikipedia.org/wiki/Digest_authentication" title="http://en.wikipedia.org/wiki/Digest_authentication" class="external text" rel="nofollow">HTTP Digest Authentication</a>
和<a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html" title="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html" class="external text" rel="nofollow">Amazon的custom S3 authentication scheme</a>
（这些都是相应到公钥/密钥的概念）。
</p>
<p>这是一个HTTP Basic 认证的应用例子，--通过Apacheht .htaccess文件保护目录/网站的账号和密码，假设我们处于<a href="http://mysite.com/protected_content" title="http://mysite.com/protected_content" class="external free" rel="nofollow">http://mysite.com/protected_content</a>
 的资源是密码保护的：
</p>
<pre>GET /protected_content HTTP/1.1
Host: mysite.com
</pre>
<p>web service 返回以下头部（header）：
</p>
<pre>HTTP/1.1 401 Authorization Required
WWW-Authenticate: Basic
..
</pre>
<p>头部里的www-Authenticate项设置为Basic，即服务端希望您使用HTTP的Basic认证（WWW-Authenticate，
这是应用在RESTful Web Services中的表示HTTP状态代码HTTP Status Codes的一个例子），现在，HTTP
Basic认证可以在Authorization的位置观察到，用户名和密码base64编码后，前置一个&quot;Basic&quot;的字符串，用分号&quot;:&quot;与
Authorization相分隔开。假设现在你的用户名是&quot;Aladdin&quot;和密码是&quot;open sesame&quot;，那你所需要提交的认证是这样的：
</p>
<pre>GET /protected_content HTTP/1.1
Host: mysite.com
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
</pre>
<p>服务器接受请求后，会对用户名和密码进行base64的解码（本例中你的密码明显是以普通文本去发送的，不过你亦可以是用HTTP的Basic认证来运行实际的web service）然后根据<strong>Authorization</strong>
规则以决定应该返回什么内容（很希望接下来的是被保护的内容）。
</p>
<p>理论上，只要在Authorzation头部进行相关设置，通过一个Ajax调用也可以完成一个这个的请求，达到相同的目的，下面就是这样一个例子，也是按照一般做法发起请求
如：
</p>
<pre>Ext.Ajax.defaultHeaders.Authorization = &quot;Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&quot;;
Ext.Ajax.request({
 url: '/protected_content',
 method: 'GET'
})
</pre>
<p>这样可以正常运行（另外很明显是你或者会定义一个快捷的函数来生成Authorization的字符串，<a href="http://extjs.com/forum/showthread.php?t=18222&amp;highlight=base64" title="http://extjs.com/forum/showthread.php?t=18222&amp;highlight=base64" class="external text" rel="nofollow">论坛上</a>
有base64编码相关的帖子）。
</p>
<p>有一个问题便是，一涉及到HTTP认证，浏览器就会自动提供帮助。如果你欲通过<strong>WWW-Authenticate</strong>
对资源发送
Basic的请求，那资源会返回401Authorization
Required的状态代码，Web浏览器这时就会提示一个登陆的对话框，并会为你进行base64的字符编码，并保存在本地缓存中，方便在每一次请求都
将这个Authorization加入头部中。本身凯说就是比较方便的，但也有下面相关的问题：
</p>
<ul>
<li> 你不可以遵循你程序外观设置样式；
</li>
<li> 你不可以通过修改Ext.Ajax.defaultHeaders的属性来重写Authorization的头部，意味着你想以别的用户身份就不太方便；
</li>
<li> 你不能从浏览器缓存中删除用户自己信任条目，意味着你记录用户登出时不太方便。
</li>
</ul>
<p>由于是使用了Ajax无刷新的表单提交，即使你提交后假设服务器不返回<strong>401 Authorization Required</strong>
的相
应，浏览器并不会自己作进一步动作，而用户也会毫不知情。在使用RESTful风格的HTTP
Basic认证效验机制下，我将用户在表单填好username/password定义到我之前安排好资源位置称作&quot;/my_account&quot;
HTTP Basic
认证效验中，逻辑句柄会向我之前定义好的称作&quot;/my_account&quot;位置获取（GETS）带有Authorization头部的表征信息
（respresentation）。如果这段respresention是空白的话，逻辑句柄就判断为安全效验的信任不获取通过。若得到的是一段通过用
户的表征信息，那么则认为登陆成功，并设置Ext.Ajax.defaultHeaders.Authorization为已认证的字符串。
</p>
<p>但是如果用户想绕过登录界面直接去访问受保护的资源时，会发生什么情形呢？可以看出，这对单页面的Ajax
Web程序不存在问题，但如果说是传统的多页面的Web程序的场景，用户很可能会收藏这个资源地址直接访问。在单页面的Web程序也有可能调用一个
RESTful的API（例如通过JavaScript或许会发送一个XHR的z请求获取一组用户列表，生成UI上的comboBox）。假设用户在浏览
器地址栏输入/api/users将会得到<strong>401 Authorization Required</strong>
的回应，显示登录的对话框并缓存结果，需要再次输入信息。感谢的是，XmlHttpRequst的设计者已经想到过这个问题，在请求的参数上加两个可选的参数，指定用户名称密码（亦进行base64的编码），<strong>不过遗憾的是，当前标准的ExtJs Ajax调用并不支持这两个可选的参数。</strong>
直到有解决方案出现之前（我想这需要一点时间）你有这些可选方案：
</p>
<ul>
<li>1  在一些浏览器上在url后面加上用户名/密码：注意一些<a href="http://support.microsoft.com/kb/834489" title="http://support.microsoft.com/kb/834489" class="external text" rel="nofollow">浏览器不支持</a>
（包括IE6以后的版本）；
</li>
<li>2  借助Doug Hendricks优秀的<a href="http://extjs.com/forum/showthread.php?t=21681" title="http://extjs.com/forum/showthread.php?t=21681" class="external text" rel="nofollow">ext-baseX.js库</a>
；
</li>
<li>3  返回一个非标准的HTTP状态代码，而不是401Authorization Required这样浏览器就不会提示，例如你可返回403Forbidden典型把这个403的代码涉及到<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" title="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" class="external text" rel="nofollow">HTTP/101标准</a>
，的内容即是Authorization不会帮助而且不应重复要求，但是你会打算取巧地使用这种方法（不足的是实用其他的Web Service会有所限制）
</li>
</ul>
<p>
<a name="Cookies.E4.B8.8ESessions"></a>
</p>
<h2><span class="mw-headline">Cookies与Sessions </span>
</h2>
<p>虽然能使用Cookies，来方便地维护Session，但是由于这是把无态的协议切换为一个有态的协议，所以并不符合RESTful的风格，本文将不会集中谈论HTTP缺失之处（若读者有兴趣了解，可阅读文章<a href="http://extjs.com/learn/Manual:RESTful_Web_Services_%28Chinese%29#Further_Reading">#Further Reading</a>
部分）。这时Cookies如果在某些应用场合如，客户端的本地储存使用，仍不算违反RESTful的建议要求。
</p>
<p>举一个例子，为了减少在不同的浏览器中来回输入登陆的信息，可以登录的信息，可在登录的表单加入&ldquo;记住我&rdquo;的单选框（checkbox），以方便用户下次登录。即使在多页面的ajax程序中你也需要这项功能来解决每次页面刷新后不能持久化的问题。
</p>
<p>要实现这种方案你可以设置在Cookies中保存用户认证的详细信息：
</p>
<pre>Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
 path: &quot;/&quot;,
 expires: new Date(new Date().getTime()+(1000*60*60*24*14)) //remember for 2 weeks
}));
Ext.state.Manager.set('auth', &quot;Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&quot;);
</pre>
<p>And then test for the existence of this cookie at app (or page) load-time and if found, use it to transparently authenticate.
</p>
<p>本质上这很明显是不安全的，任何人都可以访问包含用户名和密码的cookie缓存，要最小限度避免这种情况你应考虑使用更高级的HTTP认
证机制，值得指出的是无数网站所普遍使用的是session-key-in-a-cookie，会很容易受到大量自身安全漏洞的攻击的，此类攻击诸如：<a href="http://en.wikipedia.org/wiki/Session_hijacking" title="http://en.wikipedia.org/wiki/Session_hijacking" class="external text" rel="nofollow">Session hijacking</a>
、<a href="http://en.wikipedia.org/wiki/Csrf" title="http://en.wikipedia.org/wiki/Csrf" class="external text" rel="nofollow">Cross-site request forgery</a>
等等。
</p>
<p>
<a name=".E5.AE.8C.E6.AF.95.E4.B9.8B.E6.A0.87.E8.AE.B0"></a>
</p>
<h2><span class="mw-headline">完毕之标记</span>
</h2>
<p>This article covers the topics where I've found myself heading
slightly off the beaten path when using Ext to talk to my own RESTful
Web Services. If you find other areas that aren't covered, as I'm sure
will happen as REST becomes more widespread, please <a href="http://blog.patspam.com/contact/" title="http://blog.patspam.com/contact/" class="external text" rel="nofollow">drop me a line</a>
 as I'd love to hear how your own experiences with REST and Ext go.
</p>
<p>
<a name=".E5.BB.B6.E4.BC.B8.E9.98.85.E8.AF.BB"></a>
</p>
<h2><span class="mw-headline">延伸阅读 </span>
</h2>
<ul>
<li> <a href="http://www.amazon.com/RESTful-Web-Services-Leonard-Richardson/dp/0596529260" title="http://www.amazon.com/RESTful-Web-Services-Leonard-Richardson/dp/0596529260" class="external text" rel="nofollow">RESTful Web Services</a>
, by Leonard Richardson and Sam Ruby, 2007 (O'Reilly) - provides a definitive guide to all things REST, as well as the <strong>Resource Oriented Architecture</strong>
 which you can use to implement highly functional, real-world RESTful Web Services.
</li>
<li> <a href="http://www.ics.uci.edu/%7Efielding/pubs/dissertation/top.htm" title="http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm" class="external text" rel="nofollow">Roy Fielding's 2000 PhD Dissertation which first coined the term REST</a>
</li>
<li> <a href="http://curl.haxx.se/" title="http://curl.haxx.se/" class="external text" rel="nofollow">curl library</a>
</li>
<li> <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" title="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" class="external text" rel="nofollow">HTTP Status Codes</a>
</li>
<li> <a href="http://en.wikipedia.org/wiki/REST" title="http://en.wikipedia.org/wiki/REST" class="external text" rel="nofollow">REST on Wikipedia</a>
 (contains links to other REST resources, no pun intended)
</li>
</ul>
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/216489#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 19 Jul 2008 13:45:50 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/216489</link>
        <guid>http://sp42.javaeye.com/blog/216489</guid>
      </item>
      <item>
        <title>构思ExtJs的按需加载方案</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/213239" style="color:red;">http://sp42.javaeye.com/blog/213239</a>&nbsp;
          发表时间: 2008年07月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          根据原作者的思路，Ext是没有在脚本层面过多考虑其依赖问题的——作者推荐的方案是登录其官方网站，有专门的依赖分析器给你生成代码。<br />时下的Ext，仅仅是通过“单根继承”的方式确立其依赖关系。因此，要分析依赖关系，最好的方法是从继承链入手，即具体代码是Ext.Extend()。<br /><br />此时修改Extend()，即必须Extend设为一回调，有两种途径实现：<br />a. 加多一个函数做壳Shell，包裹着Extend。这个比较简单，但略显Hack；<br />b. Function.createInterper()作AOP，实现回调有困难，待验证。<br /><br />无论a,b方案，都是得知依赖关系后，页面动态生成script tag加载所需脚本的。<br /><br />当前方案ExtJS Only。<br /><br />今晚收获的是一个比较切题的函数：<br /><br /><pre name="code" class="javascript">/**
 * 
 * defineLiteral('bar', 'baz', 'qux', 'quux'); // => bar.baz.qux.quux
 * bar.baz.qux.quux.toString(); // => 'bar.baz.qux.quux'
 */
function defineLiteral() {
  var o = window, args = arguments, prop;
  for (var i=0, l = arguments.length; i>l; ++i) {
    prop = arguments[i];
    o[prop] = o[prop] || { }; o = o[prop];
    if (i == l-1) o['toString'] = function() {
      return Array.prototype.join.call(args, '.')
    }
  }
  return o;
} </pre>
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/213239#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Jul 2008 22:21:25 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/213239</link>
        <guid>http://sp42.javaeye.com/blog/213239</guid>
      </item>
      <item>
        <title>Erlang  Javascript v.s SquirrelFish</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/211789" style="color:red;">http://sp42.javaeye.com/blog/211789</a>&nbsp;
          发表时间: 2008年07月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          浏览器引擎WebKit小组正在忙一件事，就是升级他们的新JS引擎：SquirrelFish（金鳞鱼）。他们强调从不同的方案中集思广益（包括Lua等）,实现更快的JS解析速度。这令我想起另一边厢的引擎: erlyjs,用函数式语言Erlang写的JS引擎，号称“Javascript Flavoured Erlang”，Erlang的特点是非常适合多核，web服务...等..<br /><br />虽然没有什么量化的测评对比，但总的来说，他们在各自不同的知识领域做着同一件事情：JS引擎。<br /><br />。。哈哈～想说的是，我们Js发烧友福分不浅啊，那么多奇人异士在为JS世界的革新前赴后继。。<br />p。s。 webkit处理JS起来已经够快的了，还要快下去，岂不是傻快？ie的那些怎么办？<br /><br /><a href="http://code.google.com/p/erlyjs/" target="_blank">http://code.google.com/p/erlyjs/</a><br /><a href="http://www.infoq.com/cn/news/2008/06/SquirrelFishAnnouncement" target="_blank">http://www.infoq.com/cn/news/2008/06/SquirrelFishAnnouncement</a>
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/211789#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 05 Jul 2008 03:59:11 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/211789</link>
        <guid>http://sp42.javaeye.com/blog/211789</guid>
      </item>
      <item>
        <title>Why Rich Internet Applications on the Desktop?</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/207908" style="color:red;">http://sp42.javaeye.com/blog/207908</a>&nbsp;
          发表时间: 2008年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          March 18th, 2008 by Ryan Stewart<br /><br />Because desktop development is hard. In order to build desktop applications you have to be a pretty good programmer because there is so much other stuff to worry about. Obviously being a good programmer is never a bad thing but it does raise the barrier to entry. And it’s a lot of work to create desktop applications. You’ve got to work with potentially hundreds of native operating system APIs and when you’re done, your application runs only on the operating system you coded it for.<br /><br />Contrast that with web development. Web development is easy. You can throw some HMTL/JavaScript on a page and *BAM* instant gratification. And usually it just works. You can use any browser anywhere to see your creation. That ease of use and quick results makes web development a lot more fun. That’s been a huge driver in the popularity of web applications. In some ways web development is development for the every-person. And people have absolutely flocked to develop for the web. It’s cross-platform, it’s fun, and its easy. So that’s where all the innovation has gone: straight into the web browser. And if you look at the past 5 years it’s hard to argue that letting more people develop has been bad. We’ve got some really fantastic web applications out there and we’ve changed the economy and the world in the process. That’s pretty powerful stuff.<br /><br />So was the desktop medium the problem? Nope, it was just the development model. What if we could take the ease/cross-platform/fun development model of the web and provide desktop functionality? That’s exactly what rich Internet applications on the desktop are trying to do and that’s Adobe AIR’s goal. There are a lot of different approaches to the “new desktop” development model and they’re all good. But desktop development isn’t just about offline access or having a desktop shortcut. It’s about capturing the full experience of web development and providing the ability to create powerful, persistent, usable desktop applications. I want to see the same level of innovation that we saw in the browser now happen on the desktop because in the end, there is no arguing that the desktop is a more powerful platform than the web browser. It has more functionality and you can still take advantage of what makes the web so great. RIAs on the desktop just get rid of some of the problems with developing for the desktop. Go give it a shot. The desktop can be fun again.<br /><br />http://onair.adobe.com/blogs/onair/2008/03/18/why-rich-internet-applications-on-the-desktop/
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/207908#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 25 Jun 2008 16:08:38 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/207908</link>
        <guid>http://sp42.javaeye.com/blog/207908</guid>
      </item>
      <item>
        <title>JavaScript“类”继承的横向比较</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/201143" style="color:red;">http://sp42.javaeye.com/blog/201143</a>&nbsp;
          发表时间: 2008年06月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          首入眼帘，代码：<br /><strong>YUI 2.5.2</strong><br /><pre name="code" class="javascript">    /**
     * Utility to set up the prototype, constructor and superclass properties to
     * support an inheritance strategy that can chain constructors and methods.
     * Static members will not be inherited.
     *
     * @method extend
     * @static
     * @param {Function} subc   the object to modify
     * @param {Function} superc the object to inherit
     * @param {Object} overrides  additional properties/methods to add to the
     *                              subclass prototype.  These will override the
     *                              matching items obtained from the superclass 
     *                              if present.
     */
    extend: function(subc, superc, overrides) {
        if (!superc||!subc) {
            throw new Error("extend failed, please check that " +
                            "all dependencies are included.");
        }
        var F = function() {};
        F.prototype=superc.prototype;
        subc.prototype=new F();
        subc.prototype.constructor=subc;
        subc.superclass=superc.prototype;
        if (superc.prototype.constructor == Object.prototype.constructor) {
            superc.prototype.constructor=superc;
        }
    
        if (overrides) {
            for (var i in overrides) {
                if (L.hasOwnProperty(overrides, i)) {
                    subc.prototype[i]=overrides[i];
                }
            }

            L._IEEnumFix(subc.prototype, overrides);
        }
    }</pre><br />然后是YUI的儿子，ExtJS：<br /><pre name="code" class="javascript">        
        /**
         * 继承，并由传递的值决定是否覆盖原对象的属性
         * 返回的对象中也增加了override()函数，用于覆盖实例的成员
         * @param {Object} subclass 子类，用于继承（该类继承了父类所有属性，并最终返回该对象）
         * @param {Object} superclass 父类，被继承
         * @param {Object} overrides （该参数可选） 一个对象，将它本身携带的属性对子类进行覆盖
         * @method extend
         */
        extend : function(){
            // inline overrides
            var io = function(o){
                for(var m in o){
                    this[m] = o[m];
                }
            };
            return function(sb, sp, overrides){
                if(typeof sp == 'object'){
                    overrides = sp;
                    sp = sb;
                    sb = function(){sp.apply(this, arguments);};
                }
                var F = function(){}, sbp, spp = sp.prototype;
                F.prototype = spp;
                sbp = sb.prototype = new F();
                sbp.constructor=sb;
                sb.superclass=spp;
                if(spp.constructor == Object.prototype.constructor){
                    spp.constructor=sp;
                }
                sb.override = function(o){
                    Ext.override(sb, o);
                };
                sbp.override = io;
                Ext.override(sb, overrides);
                return sb;
            };
        }()</pre><br /><br />注：上一个是v2.0的；ExtJS v2.1改进了一点，见：<br /><pre name="code" class="javascript">
        /**
         * Extends one class with another class and optionally overrides members with the passed literal. This class
         * also adds the function "override()" to the class that can be used to override
         * members on an instance.
         * * &lt;p>
         * This function also supports a 2-argument call in which the subclass's constructor is
         * not passed as an argument. In this form, the parameters are as follows:&lt;/p>&lt;p>
         * &lt;div class="mdetail-params">&lt;ul>
         * &lt;li>&lt;code>superclass&lt;/code>
         * &lt;div class="sub-desc">The class being extended&lt;/div>&lt;/li>
         * &lt;li>&lt;code>overrides&lt;/code>
         * &lt;div class="sub-desc">A literal with members which are copied into the subclass's
         * prototype, and are therefore shared among all instances of the new class.&lt;p>
         * This may contain a special member named &lt;tt>&lt;b>constructor&lt;/b>&lt;/tt>. This is used
         * to define the constructor of the new class, and is returned. If this property is
         * &lt;i>not&lt;/i> specified, a constructor is generated and returned which just calls the
         * superclass's constructor passing on its parameters.&lt;/p>&lt;/div>&lt;/li>
         * &lt;/ul>&lt;/div>&lt;/p>&lt;p>
         * For example, to create a subclass of the Ext GridPanel:
         * &lt;pre>&lt;code>
    MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
        constructor: function(config) {
            // Your preprocessing here
        	MyGridPanel.superclass.constructor.apply(this, arguments);
            // Your postprocessing here
        },

        yourMethod: function() {
            // etc.
        }
    });
&lt;/code>&lt;/pre>
         * &lt;/p>
         * @param {Function} subclass The class inheriting the functionality
         * @param {Function} superclass The class being extended
         * @param {Object} overrides (optional) A literal with members which are copied into the subclass's
         * prototype, and are therefore shared between all instances of the new class.
         * @return {Function} The subclass constructor.
         * @method extend
         */
        extend : function(){
            // inline overrides
            var io = function(o){
                for(var m in o){
                    this[m] = o[m];
                }
            };
            var oc = Object.prototype.constructor;
            
            return function(sb, sp, overrides){
                if(typeof sp == 'object'){
                    overrides = sp;
                    sp = sb;
                    sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
                }
                var F = function(){}, sbp, spp = sp.prototype;
                F.prototype = spp;
                sbp = sb.prototype = new F();
                sbp.constructor=sb;
                sb.superclass=spp;
                if(spp.constructor == oc){
                    spp.constructor=sp;
                }
                sb.override = function(o){
                    Ext.override(sb, o);
                };
                sbp.override = io;
                Ext.override(sb, overrides);
                sb.extend = function(o){Ext.extend(sb, o);};
                return sb;
            };
        }(),</pre><br />其实啊，EXT好、YUI也好，它们那一套的继承都源自这个前辈<a href="http://www.kevlindev.com/blog/" target="_blank">Kevin Lindsey</a>：<br />要搞清楚这套继承来龙去脉，这Article就千万不能错过了：<br /><a href="http://kevlindev.com/tutorials/javascript/inheritance/index.htm" target="_blank">http://kevlindev.com/tutorials/javascript/inheritance/index.htm</a><br />问世时间是：Saturday, April 13th, 2002 。<br /><br />最后，看到一位<a href="http://stauren.net/log/eggxfygvg.html" target="_blank">仁兄的推荐</a>，来自<a href="http://ejohn.org/blog/simple-javascript-inheritance/" target="_blank">John Resig的方案</a>好像“集百家之所长”，见：<br /><br /><pre name="code" class="javascript">// Inspired by base2 and Prototype
(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

  // The base Class implementation (does nothing)
  this.Class = function(){};
 
  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;
   
    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;
   
    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
           
            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
           
            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);       
            this._super = tmp;
           
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }
   
    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }
   
    // Populate our constructed prototype object
    Class.prototype = prototype;
   
    // Enforce the constructor to be what we expect
    Class.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;
   
    return Class;
  };
})();
</pre><br />还有其他基于类的继承方案，如<a href="http://ajaxpatterns.org/Lazy_Inheritance" target="_blank">Lazy Inheritance</a>、Dean Edwards的Base2，不是说不好，而是很好，好到太复杂了（Lazy Inheritance的简介像论文似的—题外话），——个人认为过于复杂有点违背JS短小精悍的意思，什么东西过了谱就不行的啦 嘿嘿 所以第一眼就枪毙了。<br /><br />总结一下..嗯 还没太多的心得，还是<a href="http://lhdesigner.spaces.live.com/Blog/cns!F06E62DFC08D0256!1573.entry" target="_blank">台湾</a>的一位朋友说得好：<br /><div class="quote_title">引用</div><div class="quote_div"><strong>無奈</strong><br />　　感覺上又回到原始時代，或者說，回到比原始時代更久遠的上古時代，連建構基本的物件架構就有許多的不便，這樣複雜的結構實在有礙思考。想必在Scripting領域的OO或甚至Design Patten又會發展成另一個Knowledge Domain吧！過去在其他物件導向語言使用的Patten，硬是要套到這上面來不見得是一件明智的作法，畢竟Script的特性就是如此，與其他語言有一定程度的差別，但也正因為如此，不是Scripting是有缺陷的語言，而是在這個領域的設計及規劃方法，全世界都欠缺足夠的經驗，因此就不像使用 Java或C#那般，可以歡歡喜喜的導入前人歸納的各種設計模式。</div><br /><br />注：本文的重点是类继承，如果采用JS原生的“原型”继承 则简单很多——请君勿鄙之，因为存在就是合理。Just take a look 原型继承 by <a href="http://javascript.crockford.com/prototypal.html" target="_blank">Douglas Crockford</a>，比标准方案Prototype = new XX(); Make Sense很多，仅是五六行代码。<br /><br /><br />更新，hedger的代码：<br />http://cspeed.net/index.php?q=aHR0cDovL3d3dy5oZWRnZXJ3b3cuY29tLzM2MC9kaHRtbC9qcy1zaW1wbGUtaW5zdGFudGlhdGlvbi5odG1s
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/201143#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 07 Jun 2008 11:36:34 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/201143</link>
        <guid>http://sp42.javaeye.com/blog/201143</guid>
      </item>
      <item>
        <title>ExtJS与状态保存</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/196598" style="color:red;">http://sp42.javaeye.com/blog/196598</a>&nbsp;
          发表时间: 2008年05月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          节选自<a href="tp://golfadept-journey.blogspot.com/2008/05/extjs-and-saving-state.html" target="_blank">作者</a>的博客：<br /><br />在我这个例子中，我将会记住tab面板显示的tab。由于这是常见的情形，我就扩展TabPanel定义一个新类：<br /><br /><br /><pre name="code" class="javascript">Ext.ux.StatefulTabPanel = Ext.extend(Ext.TabPanel, {
 stateEvents: ['tabchange'],
 getState: function() {return{tab:this.getActiveTab().id}},
 applyState: function(state) {this.setActiveTab(state.tab);}
});</pre><br /><br />要配合运作，系统需要一个状态管理器（state manager），用于负责保存状态的数据。实际上系统内已有一个状态管理器在cookie中。如果你想保存在服务器上就另须一个别的状态管理器。按照我的经验我是比较倾向于使用浏览器的cookies来保存用户的机器的信息。这里我希望它存活的比默认的一天长：<br /><br /><pre name="code" class="javascript">Ext.state.Manager.setProvider(
 new Ext.state.CookieProvider({
  expires: new Date(new Date().getTime()+(1000*60*60*24*365)), //一年后
 }));</pre><br /><br /><br />在开始位置的Ext.onReady函数中加上以上的代码。<br /><br />处理过程不是太复杂，只需用到applyState()的方法。如果你只是需要保存某些现有的字段 可隐式调用applyState（学习疑问：重写便可？）。 本例中，根据键值activeTab来设置活动的tab：<br /><br /><pre name="code" class="javascript">Ext.ux.StatefulTabPanel = Ext.extend(Ext.TabPanel, {
 stateEvents: ['tabchange'],
 getState: function() {return{activeTab:this.getActiveTab().id}},
});</pre><br /><br />************<br />有意思的是，作者是一个拥有28年软件开发经验的50岁前辈！
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/196598#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 24 May 2008 22:54:15 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/196598</link>
        <guid>http://sp42.javaeye.com/blog/196598</guid>
      </item>
      <item>
        <title>EXT中xtype的含义</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/191657" style="color:red;">http://sp42.javaeye.com/blog/191657</a>&nbsp;
          发表时间: 2008年05月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: large">序言</span><br /><br />根据我在论坛上的观察，xtype用起来的时候疑惑会比较多。甚至有些人根本忽略xtype，或者不清楚它是什么。所以我决定阐述一下这个xtype的概念。 <br /><br /><span style="font-size: large">定义</span><br /><br />xtype就是一个代表类（Class）的标识名字。 <br /><br />譬如，你有这个类，名字是Ext.ux.MyGrid。正常情况下你需要用这个名字来实例化这个类（创建类的对象）。 <br /><br />除了类名外，你还可以这样登记类的xtype： <br />Ext.reg('mygrid', Ext.ux.MyGrid);<br /><br />其中<strong>xtype </strong>是 mygrid 而类名的一般形式是Ext.ux.MyGrid。上面的语句登记了新的<strong>xtype</strong>，换种说法说，<strong>xtype</strong> mygrid 与类 Ext.ux.MyGrid是连在一起的。 <br /><br />到底有什么好处？<br /><br />试想一下，你手头上的是一个大型的项目，为了响应用户的操作，程序里面包含者大量的对象（windows、forms、grids）。用户点击图标或按钮，就会新建一个窗体，窗体里面又有grid，最终在屏幕上渲染出来。 <br /><br />嗯，我们回到Ext2.x之前的编码，那时候我们实例化所有对象是页面第一次加载后就进行的（程序代码第一次的运行）。在客户端内存中，Ext.ux.MyGrid类的对象已经存在，等待用户的点击。 同样是这个grid，假设你上百个的实例，...是多么浪费宝贵的资源啊！很多grid其实用户未必会点击让它出现。 <br /><br /><span style="font-size: large">延时实例化</span><br /><br />如果你使用xtype，那么在内存中的仅仅是一个配置项对象，像： <br /><pre name="code" class="java">{xtype:'mygrid", border:false, width:600, height:400, ...}</pre><br /><br />消耗没有复杂的实例对象来得大。 <br /><br />嗯，用户点击按钮或图标会怎么样呢？Ext会辨认出它是一个准备要渲染的grid但不立刻实例化，Ext在ComponentMgr的帮忙下明白这么一回事：“如果我要实例化xtype mygrid的对象，我就知道要创建的实际是类Ext.ux.MyGrid的对象”。即如下列代码： <br /><br /><br /><pre name="code" class="java">create : function(config, defaultType){
    return new types[config.xtype || defaultType](config);
}
</pre><br />等价于： <br /><pre name="code" class="java">return new Ext.ux.MyGrid(config);</pre><br /><br />然后实例化grid，进行渲染和显示。谨记：<strong>需要的时候才实例化</strong>。
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/191657#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 10 May 2008 09:11:56 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/191657</link>
        <guid>http://sp42.javaeye.com/blog/191657</guid>
      </item>
      <item>
        <title>辨析Ext Extensions（扩展）与Plugins（插件）之间的关系</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/188825" style="color:red;">http://sp42.javaeye.com/blog/188825</a>&nbsp;
          发表时间: 2008年05月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>序言</strong><br /><br />要是在Ext框架中没有相应的功能，我想许多用户都会自己写一套程序去实现。有一些功能是根据他们的程序而开发的，有些则是通用的，这样其他用户可能就会对此感兴趣。 <br /><br />嗯~我们有了想法了，是需要写一写新的代码，相关的步骤我也懂得，可能面临一个问题，究竟是写扩展（Extension）还是写插件（Plugin）呢？ <br /><br /><strong>扩展与插件</strong><br /><br />我们把两样东西放在一起讨论，可以明确它们之间是有某种很相似的地方。相似的地方在于，它们都是对现有的库的功能进行 修改 或加入新的功能。 <br /><br />扩展与插件均不能独立使用；它们须依赖组件、类运行。 <br /><br /><strong>扩展</strong><br /><br />扩展（extension）在Ext中就是指衍生的子类。假设我们已经有一个附有一些方法的基类，现在欲加入新方法。我们可以框架的继承特性和JavaScript创建新类的语言特性组合新的一个类，包含基类的方法和加入的新方法。 <br /><br />我们这里进行Ext类的扩展。 首先执行函数Ext.extend返回一个新的类，这个类的名称就是新的变量名。 像下例： <br /><pre name="code" class="javascript">MyExtension = Ext.extend(Ext.Panel, {/* 对象的新属性、新方法 */});</pre><br /><br />接着，我们需要实例化对象： <br /><pre name="code" class="javascript">var myExtension = new MyExtension({/* 可选的配置项 */});</pre><br /><br /><strong>插件</strong><br /><br />插件不需要从任何Ext类为基础。尽管插件很多时候从Ext.util.Observable哪里扩展，但这不是必须的； 插件其实是可以很灵活的。如果这个插件是为某个组件服务的，就当然没有必要从现有的Ext类：panel,form,grid...写起。 <br /><br />举一个例子，说明如何创建插件： <br /><pre name="code" class="javascript">MyPlugin = function() {/* 代码 */};</pre><br /><br />然后这样子使用： <br /><pre name="code" class="javascript">var myPanel = new Ext.Panel({
     plugins:[new MyPlugin({/* 可选的配置项 */})]
    ,// 其他myPanel的配置项
});</pre><br /><br /><strong>扩展还是插件？</strong><br /><br />这要看... 无论写扩展还是写插件都可以达到相同的效果。有的程序员就喜欢写插件，有的喜欢写扩展。总得来说，小一点的功能写成插件，复杂一点的可以写成扩展。插件可以轻松地从组件上移除，扩展就和程序联系很紧密。 <br /><br /><strong>总结</strong><br /><br />一个扩展就是一个新名字出现的一个新类，它是以某个基类为基础，属于类库中的一员。扩展必须好像其他类那样实例化般地使用。<br />插件会把插入到现有的某个类之中，可灵活地移除，它可以在类库中定义，然后伴随某个类实例化的时候参与运作。<br /><br /><strong>延伸阅读</strong><br /><br /><a href="http://www.ajaxjs.com/blog/" target="_blank">这是译者的UI blog。</a><br /><a href="http://extjs.com/learn/Tutorial:Extending_Ext2_Class" target="_blank">Extending an Ext Class</a><br /><a href="http://extjs.com/learn/Tutorial:Writing_Ext_2_Plugins" target="_blank">Writing an Ext Plugin</a>
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/188825#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 02 May 2008 12:21:20 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/188825</link>
        <guid>http://sp42.javaeye.com/blog/188825</guid>
      </item>
      <item>
        <title>答复: 如何本地化ext</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/187230" style="color:red;">http://sp42.javaeye.com/blog/187230</a>&nbsp;
          发表时间: 2008年04月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          是的<br />原文在<br /><a href="http://extjs.com/learn/Tutorial:Localizing_Ext" target="_blank">http://extjs.com/learn/Tutorial:Localizing_Ext</a><br />里面的实例应该可以运行吧？
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/187230#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 27 Apr 2008 09:32:25 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/187230</link>
        <guid>http://sp42.javaeye.com/blog/187230</guid>
      </item>
      <item>
        <title>如何本地化ext</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/186973" style="color:red;">http://sp42.javaeye.com/blog/186973</a>&nbsp;
          发表时间: 2008年04月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>引言</strong><br /><br />如果你是英语的用户就不必做任何本地化的工作了，这篇教程是为非英语用户所准备的，好像一般的用户，开发主管，业务员等，他们的外语可能稍逊，这样就需要你对如何本地化ext的整个流程了解一番了。<br /><br /><strong>慢慢开始</strong><br /><br />如果你曾浏览Ext 2.x目录的树状结构，你就会发现source/locale的目录（或SVN目录的src/locale）。此目录包含了Ext本地化类。先不长篇大论地讲太多概念的东西，我们应了解如何先使用。<br /><br /><br />下面的一个例子就是使用了本地化的ext，但是不是在ext同一个目录下的。因此通常的，你需要调整head标签内的路径，以正确指向Ext的安装目录。尤其注意本地化文件的那个目录路径。<br /><br />把你服务器的路径Copy and paste到相应文件路径中： <br /><br /><strong>注意： 下里的代码我是动态加载到head头部的，只能在FireFox通过。不过实际情况你不必如此，你只要在服务端指定script的路径而不必动态加载。 </strong><br /><br /><pre name="code" class="html">&lt;html>
&lt;head>
    &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    &lt;link rel="stylesheet" type="text/css" href="../ext/resources/css/ext-all.css">
    &lt;script type="text/javascript" src="../ext/adapter/ext/ext-base.js">&lt;/script>
    &lt;script type="text/javascript" src="../ext/ext-all-debug.js">&lt;/script>
    &lt;script type="text/javascript">
 
    //根据url上指定的语言进行解码
    var locale = window.location.search 
                 ? Ext.urlDecode(window.location.search.substring(1)).locale 
                 : '';
 
    // 将本地化的JS文件加入head元素内
    var head = Ext.fly(document.getElementsByTagName('head')[0]);
    if(locale) {
        Ext.DomHelper.append(head, {
             tag:'script'
            ,type:'text/javascript'
            ,src:'../ext/src/locale/ext-lang-' + locale + '.js'
        });
    }
 
    //预先定义的window继承类
    Ext.ns('Tutorial');
    Tutorial.LocalizationWin = Ext.extend(Ext.Window, {
        initComponent:function() {
            Ext.apply(this, {
                 width:500
                ,id:'winid'
                ,height:300
                ,layout:'fit'
                ,border:false
                ,closable:false
                ,title:Ext.get('title').dom.innerHTML
                ,items:[{
                     xtype:'form'
                    ,frame:true
                    ,defaultType:'textfield'
                    ,items:[{
                          xtype:'combo'
                         ,fieldLabel:'Select Language'
                         ,name:'locale'
                         ,store:new Ext.data.SimpleStore({
                             id:0
                            ,fields:['file', 'locale']
                            ,data:[
                                 ['cs', 'Czech']
                                ,['', 'English']
                                ,['fr', 'French']
                                ,['de', 'German']
                                ,['gr', 'Greece']
                                ,['hu', 'Hungarian']
                                ,['it', 'Italian']
                                ,['ja', 'Japaneese']
                                ,['pl', 'Polish']
                                ,['pt', 'Portugal']
                                ,['ru', 'Russian']
                                ,['sk', 'Slovak']
                                ,['es', 'Spanish']
                                ,['sv_SE', 'Swedish']
                                ,['tr', 'Turkish']
                            ]
                         })
                        ,listeners:{
                            select:{fn:function(combo){
                                window.location.search = '?' 
                                    + Ext.urlEncode({locale:combo.getValue()})
                                ;
                            }}
                        }
                        ,mode:'local'
                        ,editable:false
                        ,forceSelection:true
                        ,valueField:'file'
                        ,displayField:'locale'
                        ,triggerAction:'all'
                        ,value:locale
                     },{
                         fieldLabel:'Text Field'
                        ,allowBlank:false
                    },{
                         xtype:'datefield'
                        ,fieldLabel:'Date Field'
                        ,allowBlank:false
                    }]
                }]
            }); // eo apply
            Tutorial.LocalizationWin.superclass.initComponent.apply(this, arguments);
        } // eo function initComponent
    }); // eo Tutorial.LocalizationWin
 
Ext.BLANK_IMAGE_URL = '../ext/resources/images/default/s.gif';
Ext.onReady(function() {
    Ext.QuickTips.init();
    Ext.form.Field.prototype.msgTarget = 'side';
 
    // create example window
    var win = new Tutorial.LocalizationWin();
    win.show();
});
    &lt;/script>
    &lt;title id="title">Localization Example&lt;/title>
&lt;/head>
&lt;body>
&lt;/body>
&lt;/html></pre><br />现在完整的本地化工作是限于ComboBox、TextField和DateField这些Ext基础组件。试试在已翻译好的DataPicker组件中输入一些文字。 <br /><br /><strong>原理是？？</strong><br /><br />原理是一改变cobmo box里面的"Select Language"就会包含（include）相应的Ext本地化文件（这里我使用了一些技巧性的做法，改变本地化文件的过程是用过客户端脚本完成的） <br /><br /><strong>本地化文件的葫芦里卖的什么药？</strong><br /><br />首先要打开本地化文件来看看，读懂里面的源码后不但对Ext的理解有帮助而且对整个程序的本地化，也是有帮助的。我们以法语版的DatePicker为例子： <br /><br /><pre name="code" class="javascript">if(Ext.DatePicker){
   Ext.override(Ext.DatePicker, {
      todayText         : "Aujourd'hui",
      minText           : "Cette date est antérieure à la date minimum",
      maxText           : "Cette date est postérieure à la date maximum",
      disabledDaysText  : "",
      disabledDatesText : "",
      monthNames        : Date.monthNames,
      dayNames          : Date.dayNames,
      nextText          : 'Mois suivant (CTRL+Flèche droite)',
      prevText          : "Mois précédent (CTRL+Flèche gauche)",
      monthYearText     : "Choisissez un mois (CTRL+Flèche haut ou bas pour changer d'année.)",
      todayTip          : "{0} (Barre d'espace)",
      okText            : "&#160;OK&#160;",
      cancelText        : "Annuler",
      format            : "d/m/y",
      startDay          : 1
   });
}</pre><br /><br />通过观察，我们得知如果DataPicker对象存在（这是需要检测的，事因有些ext是你自己可制定的）就重写DataPicker的部分属性；更严格说，我们是把法语的文字替换掉英语的文字而已。Ext.override的作用是在DatePicker建立实例之前改变class的原型。 <br /><br /><strong>应用程序的本地化</strong><br /><br />我们对范例文件略加修改，把所有的静态文本变为类成员，修改过后看起来是这样的： <br /><pre name="code" class="html">&lt;html>
&lt;head>
    &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    &lt;link rel="stylesheet" type="text/css" href="../ext/resources/css/ext-all.css">
    &lt;script type="text/javascript" src="../ext/adapter/ext/ext-base.js">&lt;/script>
    &lt;script type="text/javascript" src="../ext/ext-all-debug.js">&lt;/script>
 
    &lt;!-- Ext localization javascript -->
    &lt;script type="text/javascript" id="extlocale">&lt;/script>
 
    &lt;!-- Locale and example extension javascript -->
    &lt;script type="text/javascript">
 
    // decode language passed in url
    var locale = window.location.search 
                 ? Ext.urlDecode(window.location.search.substring(1)).locale 
                 : ''
    ;
 
    // append locale script to the head
    var head = Ext.fly(document.getElementsByTagName('head')[0]);
    if(locale) {
        Ext.fly('extlocale').set({src:'../ext/src/locale/ext-lang-' + locale + '.js'});
    }
 
    // create pre-configured example window extension class
    Ext.ns('Tutorial');
    Tutorial.LocalizationWin = Ext.extend(Ext.Window, {
         titleText:'Localization Example'
        ,selectLangText:'Select Language'
        ,textFieldText:'Text Field'
        ,dateFieldText:'Date Field'
        ,initComponent:function() {
            Ext.apply(this, {
                 width:500
                ,id:'winid'
                ,height:300
                ,layout:'fit'
                ,border:false
                ,closable:false
                ,title:this.titleText
                ,items:[{
                     xtype:'form'
                    ,frame:true
                    ,defaultType:'textfield'
                    ,items:[{
                          xtype:'combo'
                         ,fieldLabel:this.selectLangText
                         ,name:'locale'
                         ,store:new Ext.data.SimpleStore({
                             id:0
                            ,fields:['file', 'locale']
                            ,data:[
                                 ['cs', 'Czech']
                                ,['', 'English']
                                ,['fr', 'French']
                                ,['de', 'German']
                                ,['gr', 'Greece']
                                ,['hu', 'Hungarian']
                                ,['it', 'Italian']
                                ,['ja', 'Japaneese']
                                ,['pl', 'Polish']
                                ,['pt', 'Portugal']
                                ,['ru', 'Russian']
                                ,['sk', 'Slovak']
                                ,['es', 'Spanish']
                                ,['sv_SE', 'Swedish']
                                ,['tr', 'Turkish']
                            ]
                         })
                        ,listeners:{
                            select:{fn:function(combo){
                                window.location.search = '?' 
                                    + Ext.urlEncode({locale:combo.getValue()})
                                ;
                            }}
                        }
                        ,mode:'local'
                        ,editable:false
                        ,forceSelection:true
                        ,valueField:'file'
                        ,displayField:'locale'
                        ,triggerAction:'all'
                        ,value:locale
                     },{
                         fieldLabel:this.textFieldText
                        ,allowBlank:false
                    },{
                         xtype:'datefield'
                        ,fieldLabel:this.dateFieldText
                        ,allowBlank:false
                    }]
                }]
            }); // eo apply
            Tutorial.LocalizationWin.superclass.initComponent.apply(this, arguments);
        } // eo function initComponent
    }); // eo Tutorial.LocalizationWin
    &lt;/script>
 
    &lt;!-- Application localization javascript -->
    &lt;script type="text/javascript" id="applocale">&lt;/script>
 
    &lt;!-- Set src for application localization javascript -->
    &lt;script>
    if(locale) {
        Ext.fly('applocale').set({src:'app-lang-' + locale + '.js'});
    }
    &lt;/script>
 
    &lt;!-- Main application -->
    &lt;script type="text/javascript">
    Ext.BLANK_IMAGE_URL = '../ext/resources/images/default/s.gif';
    Ext.onReady(function() {
        Ext.QuickTips.init();
        Ext.form.Field.prototype.msgTarget = 'side';
 
        // create example window
        var win = new Tutorial.LocalizationWin();
        win.show();
    });
    &lt;/script>
    &lt;title id="title">Localization Example&lt;/title>
&lt;/head>
&lt;body>
&lt;/body>
&lt;/html></pre><br /><br />最后一步，我们需要为特定的语种创建程序本地化的文件（翻译，语种）。这里是app-lang-sk.js文件因为我操的是斯洛伐克语的缘故。你可因应你需求的语种去设置（保存html的格式放到同一目录下或修改上面代码的目录）： <br /><pre name="code" class="javascript">
/**
 * 斯洛伐克语版的教程之本地化文件
 */
if(Tutorial.LocalizationWin) {
    Ext.override(Tutorial.LocalizationWin, {
         titleText:'Príklad lokalizácie'
        ,selectLangText:'Zvoľ jazyk'
        ,textFieldText:'Textové pole'
        ,dateFieldText:'Dátumové pole'
    });
}</pre><br /><br /><strong>高级提示</strong><br /><br />请明确，要做Ext程序的本地化需要遵循哪些的原则。关键点在于将所有翻译文本作为公共类的成员出现，重写原先类的prototype的属性。<br /><br />这种做法最大的好处是可讲翻译文件集中在一块(*.po)，客户端和服务端都可以使用。<br /><br />如果本地化这主题反映还不错的话而读者又非常想进一步了解我会写进阶的Ext本地化。<br /><br />Enjoy!
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/186973#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 26 Apr 2008 00:31:16 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/186973</link>
        <guid>http://sp42.javaeye.com/blog/186973</guid>
      </item>
      <item>
        <title>EXT新手建议：建立自己的工具箱（Toolkit）</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/179990" style="color:red;">http://sp42.javaeye.com/blog/179990</a>&nbsp;
          发表时间: 2008年04月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          欢迎来到论坛<br /><br />我认为学习EXT开发最好的方法是，在真正开发之前，掌握好高级JavaScript知识，<br />就像鱼儿游在水里一样对JS运用自如。<br /><br />自己可以创建JavaScript的类、明白类原型（class's prototype）的原理，<br />和明白函数的作用域都是有益的帮助。<br /><br />明白Ajax为什么要异步方式也是其中的一个知识点。<br /><br />论坛上50％所提出的问题很大原因是对JavaScript知识不牢固所至，而不是EXT API的问题。<br /><br />当真正开始用EXT做开发了，那么安装目录下examples/*的文件夹超过70个例子便是研究的好对象，<br />这些例子为你展示了你日后将会使用的大多数技巧或方法。<br /><br />接着，最好就是先拿examples/*的文件夹中例子练一练手，做一些简单、轻型的小项目。<br />如果直接拿EXT结合到程序去开发，很可能你会因为越来越复杂的问题泥足深陷。<br /><br />把每一项的 知识点/技巧 都做成可单独运行文件，这样以便你以后参考，还有一个好处是，可以发到论坛上，然后我们放到examples/*的文件夹，以便我们的测试并协助你。<br /><br />如果能按照以上的建议去做，我相信这是一个很好的累积。而且按照我的角度看，整个UI就是这样一点一点构建起来。<br />	<br />Animal
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/179990#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 07 Apr 2008 09:40:35 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/179990</link>
        <guid>http://sp42.javaeye.com/blog/179990</guid>
      </item>
      <item>
        <title>Notes on JavaScript functions and objects</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/179833" style="color:red;">http://sp42.javaeye.com/blog/179833</a>&nbsp;
          发表时间: 2008年04月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Notes on JavaScript functions and objects<br /><br />Notes on JavaScript functions and objects<br />functions<br />static (or definition) context<br /><br />    * All functions have a property named prototype.1 The value of prototype is an object2 with a property named constructor.3 The value of constructor is the function itself.4<br />    * All functions have a property called length which specifies the expected number of parameters.5<br />    * The value of constructor property of a function is function Function6 that is because the hidden super instance of a function is the value of the prototype property of function Function.7<br /><br />execution context<br /><br />    * While a function executes there is a special variable arguments holds the actual arguments that were passed in when the function was invoked.<br />    * While a function executes there is a special variable arguments is of type Arguments which is an array-like object with a property length which gives the number of actual parameters passed in during invocation.<br />    * While a  function executes there is a special variable arguments.callee holds a reference to the function object itself. Thus  arguments.callee.length gives us the number of expected parameters.<br /><br />Function function<br />static (or definition) context<br /><br />    * Function being a function has a property named prototype. The value of prototype is an anonymous function function(){} with a property named constructor. The value of constructor is the function Function.<br />    * The value of constructor property of function Function is function Function. That is because the hidden super instance of a function is the value of the prototype property of function Function.<br /><br />objects such as {} or new Object()<br /><br />    * The constructor of an object such as {} or new Object{} of course is function Object.8<br />    * All objects inherit properties from a hidden super instance - the prototype object. The prototype object is the same as the value of the prototype property of function which was used to create the object using the new operator. Note: objects do not have a property named prototype.<br />    * The inherited properties behave in a copy-on-set manner.<br />    * All objects inherit a property named constructor from their hidden super instance - the prototype object.9<br /><br />Object function<br />static (or definition) context<br /><br />    * Object being a function has a property named prototype. The value of prototype is an anonymous object {} with a property named constructor.10 The value of constructor is the function Object.11<br />    * The value of constructor property of function Object is function Function. That is because the hidden super instance of a function is the value of the prototype property of function Function.<br /><br />Let us say we have code like this:<br /><br />function Rectangle(width, height) { <br />    this.width = width;             <br />    this.height = height;           <br />}                                   <br /><br />var twoByFourRectangle = new Rectabgle(2, 4);<br /><br />           +--------------------------------------+                                                                                  <br />  inherits | +---------constructor property ----+ |                          +----------------------------------+                    <br />    from   | |                                  | |        inherits          |                                  |                    <br />           | v                                  | v         from             v                                  |                    <br />function Function --- prototype property---> function(){} &lt;----- function Object --- prototype property---> {constructor: Object}    <br />                                               ^                                                            ^                        <br />                                      inherits | +---------------------------------------+                  |                        <br />                                        from   | |                                       |                  | inherits               <br />                                               | v                                       |                  |  from(?)               <br />                                  function Rectangle --- prototype property ----> {constructor: Rectangle}--+                        <br />                                                                                  ^<br />                                                                         inherits |<br />                                                                           from   |<br />                                                                                  |<br />                                                                 object twoByFourRectangle --- width property ----> 2<br />                                                                                           +--- height property --> 4<br /><br />1  alert("prototype" in Rectangle);                   => 'true'<br /><br />2  alert(Rectangle.prototype);                        => '[object Object]'<br /><br />3  alert("constructor" in Rectangle.prototype);       => 'true'<br /><br />4  alert(Rectangle.prototype.constructor);            => '[function Rectangle]'<br /><br />5  alert(Rectangle.length);                           => '2'<br /><br />6 alert(Rectangle.constructor) => 'function Function() {[native code]}'<br /><br />7  alert(Rectangle.constructor.prototype)             => 'function(){}'<br /><br />8  alert({}.constructor);                             => 'function Object() {[native code]}'<br /><br />9 alert("constructor" in {}); => 'true'<br /><br />10 alert(Object.prototype); => '[object Object]'<br /><br />11 alert(Object.prototype.constructor);               => 'function Object() {[native code]}'<br /><br />TIP: You can evaluate expressions like the above in the Firefox's Tools:Error Console's Evaluate text field.<br /><br /><br />Tricky huh? It was for me.
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/179833#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 06 Apr 2008 14:28:14 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/179833</link>
        <guid>http://sp42.javaeye.com/blog/179833</guid>
      </item>
      <item>
        <title>JavaScript：从最受误解的编程语言演变为最流行的语言</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/178525" style="color:red;">http://sp42.javaeye.com/blog/178525</a>&nbsp;
          发表时间: 2008年04月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.amazon.com/exec/obidos/ASIN/B000OIVLUQ/wrrrldwideweb" target="_blank">《计算机语言：历史与基石》</a>一书由Jean Sammet写于1969年。此书的内容是对120种编程语言的考查，其中一些语言有详尽的简介。Sammet这本语言编年史写在结构化编程革命（Structured Programming Revolution）、随后的面向对象编程之前。书籍以一张巴别塔（Tower of Babel，又译通天塔。见译注。）的图片作封面。塔身由砖块围成，围在里面的是各种名称的编程语言。<br /><br /><em>译注：巴别塔，《圣经》中的通天塔，大洪水之后诺亚的子孙繁衍，并试图建造通天塔直通天界，上帝不爽，于是给他们创造了不同的语言，语言隔阂、交流障碍，通天塔轰然倒塌。</em><br /><br />这是大家熟知的《圣经Genesis》[11:1-9]的故事：<br /><br /><div class="quote_title">引用</div><div class="quote_div"> 耶和华降临，要看看世人所建造的城和塔。耶和华说，看哪，他们成为一样的人民，都是一样的言语，如今既作起这事来，以后他们所要作的事就没有不成就的了。我们下去，在那里变乱他们的口音，使他们的言语彼此不通。于是，耶和华使他们从那里分散在全地上。他们就停工，不造那城了。因为耶和华在那里变乱天下人的言语，使众人分散在全地上，所以那城名叫巴别（就是变乱的意思）。</div><br /><br />这段意思有时理解为做人不能太傲慢；有时理解为一个寓言故事，告诉你为什么人们在说不同的语言：耶和华为防止人们达到自己的潜能而制造了i18N问题。不过我想把这个道理放到编程语言上去理解也是如此。编程根本问题在于对复杂问题的掌控能力。如果语言在需求变化时未能帮助我们处理复杂的系统，而最终令人感到混乱，自然离失败不远。<br /><br />为何有如此之多的编程语言？不计Sammet当时的数量，过去四十年已经有大量的新语言或方言问世。我们已经在好长的时间内是在一个高级（High Level）的环境下编程了。那么我们应不应该就遵循某种恰当的方式来做呢？毫无疑问，能够以同一种绝佳的语言进行设计所带来的效率是很明显的。我们可以更有效地集中资源来配合来培训或工具的研发。为什么我们还不这样子做？<br /><br />我们已经努力过。现在已经有几种语言尝试构建起大规模的、通用的语言，结果却是失败了。随着语言设计的不断更新，加入更多的功能，从而变得越来越复杂。<br /><br />因此我们看到取而代之的是许多的专用语言。在完成一些任务的领域中，专用语言可以非常高效地解决，而且是足够好的。对于要完成此类任务的人而言，选择好的语言，自然是如虎添翼。<br /><br />一门编程语言从某些表达式的语法的运算得到模型的修正。大多数语言有一组常用的值如数字和文本（numbers、texts 在大多数语言中，奇怪地称作字符串），和若干的操作，如改变和合成值，或一些变量和循环的操作，还有就是把一些常用的操作打包到命令中。<br /><br />变化是行如幻影，变化莫测，就像一道菜和一首乐曲每一次都不尽相同。语言设计的艺术在于清楚哪些是舍的（leave out）。一门良好语言，它里面的功能应该是和谐地工作在一起，帮助我们更好地明白问题和找出解决方案的最佳表达方式（the best expression of its solutio）。<br /><br />一门好的语言有几组功能所构成，但是哪一项的功能才是最好的就永远没有结论。程序员可以不断地讨论这个话题和是否比其他的语言优秀。这里不是说功能不重要。功能它非常重要。只不过我们还没清楚它真的这么重要。<br /><br />时髦与技术之间语言设计需要做更多的是在时髦方面。时髦是nerdliest艺术中一种主要的因素，可能看起来很奇怪，但的确是一点不假。无论语言的设计有多么精巧，若以一个另类的语法出现的话，是没有希望得到广泛使用的。这样会约束了语言的进化。<br /><br />像音乐和食物一样，编程语言也属于时间的产物。语言设计的深层问题不是技术上的，是心理上的问题。一门编程语言应该与我们认知的结构相吻合，以便更高效率地帮助我们判断问题。<br /><br />编程语言像猫这种动物，换一只猫总比把一只旧的猫驯化容易些。按照常理，大多数语言成功后由后来的升级版所取缔。重新规划的语言几乎很少到达旧版那种成就。 Fortan曾经是语言翘楚，好些年在不断改进，但Fortran IV的声誉非现代化后的Fortran方言所能及。类似地，Pascal是结构化编程的流行语言，但其OO的版本难盖原Pascal之光芒。结果，它渐渐被取代。<br /><br /><br />专用语言做起来是挺有意思的，这也解释了它们的数量为什么如此地多。如果一门语言不太庞大，那么一个程序员就可以掌控它了。大多数语言可以由一个设计师创出出来。Pascal: Wirth。C: Ritchie。C++: Stroustrup。Java: Gosling. C#:Hejlsberg。Rebol: Sassenrath.。Python: van Rossum.PHP: Lerdorf. Perl:Wall. Ruby: Matsumoto。 Lua: Ierusalimschy. E:Miller。JavaScript: Eich。<br /><br />大多数语言失败在于不够清晰。而剩下不多的语言能够一直在单个项目或公司中使用下去。也只有极少数量的语言成为重要的语言。<br /><br />两种途径会使某种语言变得更重要。第一它是能让思想光辉发射光芒。Smalltalk和Scheme都具备这种特质，虽然这些语言并不广泛使用，现在看也是过时的，但它们公认为是杰出的语言，并对后来的语言设计带来深远的影响。<br /><br />第二种体现在语言的流行程度，说明了语言的重要性。<br /><br />程序员在选择一门编程语言的时候，很多东西必须再三考虑，不过到了编写web浏览器的时候当前唯一的选择便是JavaScript。<br /><br />JavaScript 是一种乖张、亦正亦邪的语言，它其貌不扬。这种乖张的特性给它带来及其糟糕的声誉。DOM文档对象模型也与JavaScript同休公戚，是一个不太讨好的API。理清了JavaScript的概念后DOM的各种乱七八糟的东西又随着来。有许多人嚷着要改进JavaScript，但就目前web开发者的状况而言可改善的余地很少。语言的功能太多，包括别扭的交互操作或失败的设计。正如Emperor Joseph所说的，这语言搞太多花样了。<br /><br />嗯，那JavaScript的缺失之处这么多，怎么还能做Web的龙头编程语言？BrendanEich就有这个本事，能够说服当时Netscape的秃头老板，要做Navigator自己的脚本语言，还要不是新的语言不去做，－就这样，匆匆忙忙地设计出一门新的语言并实现出来，还真的没有别的语言能代替这种需求。为了能蚕食Netscape的市场份额，微软的IE团队通过逆向工程小心翼翼地得到Netscape的语言，明显有许多不足但也不管三七二十一了。其他浏览器厂商亦效仿微软的做法，因此不存在web浏览必须实现的是标准的JavaScript之说法。除了JavaScript外，没有其他语言的实现可以在浏览器内全部行得通。互联网发展一切都是未知，因此不存在对语言仔细地调研，并且从来就没有什么实用性调研或完整的设计。它只是出自 Netscape之手，然后不断被复制而已。若我们刻意、人为地创造一个类似JavaScript的东东而且还有建立一个标准，那么说不定这不是我们想要的。<br /><br />尽管JavaScript充满着缺点，但深入其内核是有许多地方错有错着的。当你一步一步慢慢到内部了解，会发现这个一个精练和强大的编程语言。许多Ajax库现在用JavaScript来处理DOM，以网页的形式来生成应用程序的交互平台。Ajax变得更为流行正因 JavaScirpt是可以的，而且还超乎我们的想象。世界上最为流行的JavaScript曾经是世界上最受误解的语言。以其明显的缺陷、不时髦的编程模型、令全世界都误导的简介与它那个不相称的名字，曾经让大多数聪明的程序员觉得毫无价值而遭到抵制。但是Ajax给了JavaSciprt第二次的机会。<br /><br />正因为JavaScript是浏览器的语言，正因为web浏览器渐渐成为传送消息程序中的重要部分，正因为JavaSscipt并不是太糟糕，JavaSciprt已经成为世界上最流行的编程语言。由于流通性在加大，同时也被一些应用程序嵌入式地使用，JavaScript已经越来越重要。<br /><br />It is better to be lucky than smart..<br /><br />作者：Douglas Crockford 08.3.3<br /><a href="http://javascript.crockford.com/popular.html" target="_blank">http://javascript.crockford.com/popular.html</a>
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/178525#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Apr 2008 18:02:39 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/178525</link>
        <guid>http://sp42.javaeye.com/blog/178525</guid>
      </item>
      <item>
        <title>Ext 2 常用布局类简介（Container、AchorLayout、FitLayout等）</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/169988" style="color:red;">http://sp42.javaeye.com/blog/169988</a>&nbsp;
          发表时间: 2008年03月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="color: #993300;">@class Ext.layout.ContainerLayout
  </span>
</p>
<p>&nbsp;</p>
<p>每一个布局都内置有一个或多个{@link Ext.Container}的元素，而在Ext中，ContainerLayout是
  ContainerLayout没有任何的外观表示，只是为特定功能的容器作为布局提供基础性的逻辑。
  应通过继承该类的方式使用，一般很少通过关键字new直接使用。
 
   </p>
<p>&nbsp;</p>
<p><span style="color: #993300;">@class Ext.layout.FitLayout
  </span>
</p>
<p><span style="color: #993300;">@extends Ext.layout.ContainerLayout</span>
  </p>
<p>&nbsp;</p>
<p>
  这是包含单个项布局的基类，这种布局会在容器上自动铺开以填充整个容器。 
  应通过继承此类或设置{@link Ext.Container#layout}的配置layout:'fit' 的方式创建，一般很少通过关键字new直接使用。
  </p>
<p>&nbsp;</p>
<p>FitLayout没有直接的配置选项（不同于继承）
  要采用FitLayout填充容器的面板，只需设置容器的layout:'fit'和加入一个面板。
  即使容器指定了多个面板，只会渲染第一个面板。用法举例：&nbsp; </p>
<pre>var p = new Ext.Panel({
    title: 'Fit Layout',
    layout:'fit',
    items: {
        title: '内层面板',
        html: '&lt;p&gt;这是内层面板的内容&lt;/p&gt;',
        border: false
    }
});
</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/169988#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 10 Mar 2008 22:17:34 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/169988</link>
        <guid>http://sp42.javaeye.com/blog/169988</guid>
      </item>
      <item>
        <title>Ext 2.02 API新增功能</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/165579" style="color:red;">http://sp42.javaeye.com/blog/165579</a>&nbsp;
          发表时间: 2008年02月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p> 为联合Adobe， <a href="http://extjs.com/download">Ext2.02</a>当中重要的一项便是针对<a href="http://www.adobe.com/go/air">AIR1.0</a>中应用程序的<a href="http://labs.adobe.com/wiki/index.php/AIR:HTML_Security_FAQ#What_exactly_is_disabled_or_restricted_in_the_Application_sandbox.3F">沙箱(Application Suadbox)</a>提供运行的支持。另外，作为范本的AIR版的Simple Tasks（简易任务）已重写以体现AIR原生功能还有一部分Ext制定组件是可以在AIR之外使用。 </p><h3>AIR APIs</h3><p>首先，一些会用到的API我们先讲讲: </p><p><strong><br />原生Window NativeWindow</strong></p><p>Ext.air包其中一项最有用的功能。此API可创建、管理Windows，例如侦听事件发挥了标准的Ext观察者和Windows自动状态管理的作用。 </p><p>&nbsp;</p><div class="wp_syntax"><div class="code"><pre class="javascript"><span style="font-weight: 700; color: #800080">var</span> win = <span style="font-weight: 700; color: #800080">new</span> Ext.<span style="color: #222222">air</span>.<span style="color: #222222">NativeWindow</span><span style="color: #222222">(</span><span style="color: #222222">{</span>     id: winId,     file: <span style="background-color: #e7e8ec; color: #008080">'task.html'</span>,     width:<span style="color: #800000">500</span>,     height:<span style="color: #800000">350</span>,     resizable: <span style="font-weight: 700; color: #800080">true</span> <span style="color: #222222">}</span><span style="color: #222222">)</span>;</pre></div></div><div style="padding: 20px"><img src="http://extjs.com/playpen/screenshots/air/task-window.png" alt="" /> <div style="font-size: 10px; text-align: center; width: 548px; margin: 5px">Task NativeWindow in Simple Tasks 2</div></div><p><strong>Ext.sql.*</strong></p>在AIR早期的beta版本中，数据库访问的方式为异步访问。随着beta3中可使用同步方式访问，Ext.data.Record亦相应提供升级的支持。<p>Simple Tasks演示了怎么在SQLite数据库中持久Ext.data.Record的实例，整合的过程并不困难。</p><p>&nbsp;</p><div class="wp_syntax"><div class="code"><pre class="javascript">tx.<span style="color: #222222">data</span>.<span style="color: #222222">ListStore</span> = Ext.<span style="color: #222222">extend</span><span style="color: #222222">(</span>Ext.<span style="color: #222222">data</span>.<span style="color: #222222">Store</span>, <span style="color: #222222">{</span>     constructor: <span style="font-weight: 700; color: #800080">function</span><span style="color: #222222">(</span><span style="color: #222222">)</span><span style="color: #222222">{</span>         <span style="font-style: italic; color: #808080">// superclass call</span>         tx.<span style="color: #222222">data</span>.<span style="color: #222222">ListStore</span>.<span style="color: #222222">superclass</span>.<span style="color: #222222">constructor</span>.<span style="color: #222222">call</span><span style="color: #222222">(</span><span style="font-weight: 700; color: #800080">this</span>, <span style="color: #222222">{</span>             sortInfo:<span style="color: #222222">{</span>field: <span style="background-color: #e7e8ec; color: #008080">'listName'</span>, direction: <span style="background-color: #e7e8ec; color: #008080">&quot;ASC&quot;</span><span style="color: #222222">}</span>,             reader: <span style="font-weight: 700; color: #800080">new</span> Ext.<span style="color: #222222">data</span>.<span style="color: #222222">JsonReader</span><span style="color: #222222">(</span><span style="color: #222222">{</span>                 id: <span style="background-color: #e7e8ec; color: #008080">'listId'</span>,                 fields: tx.<span style="color: #222222">data</span>.<span style="color: #222222">List</span>             <span style="color: #222222">}</span><span style="color: #222222">)</span>         <span style="color: #222222">}</span><span style="color: #222222">)</span>; &nbsp;         <span style="font-weight: 700; color: #800080">this</span>.<span style="color: #222222">conn</span> = tx.<span style="color: #222222">data</span>.<span style="color: #222222">conn</span>;         <span style="font-style: italic; color: #808080">// Ext.sql.Proxy for managing Sqlite persistence</span>         <span style="font-weight: 700; color: #800080">this</span>.<span style="color: #222222">proxy</span> = <span style="font-weight: 700; color: #800080">new</span> Ext.<span style="color: #222222">sql</span>.<span style="color: #222222">Proxy</span><span style="color: #222222">(</span>tx.<span style="color: #222222">data</span>.<span style="color: #222222">conn</span>, <span style="background-color: #e7e8ec; color: #008080">'list'</span>, <span style="background-color: #e7e8ec; color: #008080">'listId'</span>, <span style="font-weight: 700; color: #800080">this</span><span style="color: #222222">)</span>;     <span style="color: #222222">}</span>,     ...</pre></div></div><p>&nbsp;</p><p><strong>原生的拖放和剪贴板</strong><br /> Simple Tasks支持拖动任意的文本拖动到Grid，自动转回为新任务（Task）。而且也可以从的系统的剪贴板粘贴新建任务，不过，其中一项最COOL的功能就是允许直接从OUTLOOK拖动任务到SimpleTask。</p><div style="padding: 20px"><img src="http://extjs.com/playpen/screenshots/air/outlook.png" alt="" /> <div style="font-size: 10px; text-align: center; width: 670px; margin: 5px">Dragging Outlook tasks into Simple Tasks</div></div><p><strong>最小化系统状态功能</strong></p><p>第一版的SimpleTask发布后，ExtJS内部这里需求最大的就是最小化window系统状态栏的功能。我们将自动控制系统托盘（System Tray）的功能加入到Ext.air.NativeWindow这个类中。这样，通过设置一下配置项就可最小化到系统托盘。</p><p>&nbsp;</p><div class="wp_syntax"><div class="code"><pre class="javascript"><span style="font-weight: 700; color: #800080">var</span> win = <span style="font-weight: 700; color: #800080">new</span> Ext.<span style="color: #222222">air</span>.<span style="color: #222222">NativeWindow</span><span style="color: #222222">(</span><span style="color: #222222">{</span>     id: <span style="background-color: #e7e8ec; color: #008080">'mainWindow'</span>,     instance: window.<span style="color: #222222">nativeWindow</span>, &nbsp;     <span style="font-style: italic; color: #808080">// System tray config</span>     minimizeToTray: <span style="font-weight: 700; color: #800080">true</span>,     trayIcon: <span style="background-color: #e7e8ec; color: #008080">'ext-air/resources/icons/extlogo16.png'</span>,     trayTip: <span style="background-color: #e7e8ec; color: #008080">'Simple Tasks'</span>,     trayMenu : <span style="color: #222222">[</span><span style="color: #222222">{</span>         text: <span style="background-color: #e7e8ec; color: #008080">'Open Simple Tasks'</span>,         handler: <span style="font-weight: 700; color: #800080">function</span><span style="color: #222222">(</span><span style="color: #222222">)</span><span style="color: #222222">{</span>             win.<span style="color: #222222">activate</span><span style="color: #222222">(</span><span style="color: #222222">)</span>;         <span style="color: #222222">}</span>     <span style="color: #222222">}</span>, <span style="background-color: #e7e8ec; color: #008080">'-'</span>, <span style="color: #222222">{</span>         text: <span style="background-color: #e7e8ec; color: #008080">'Exit'</span>,         handler: <span style="font-weight: 700; color: #800080">function</span><span style="color: #222222">(</span><span style="color: #222222">)</span><span style="color: #222222">{</span>             air.<span style="color: #222222">NativeApplication</span>.<span style="color: #222222">nativeApplication</span>.<span style="color: #222222">exit</span><span style="color: #222222">(</span><span style="color: #222222">)</span>;         <span style="color: #222222">}</span>     <span style="color: #222222">}</span><span style="color: #222222">]</span> <span style="color: #222222">}</span><span style="color: #222222">)</span>;</pre></div></div><div style="padding: 20px"><img src="http://extjs.com/playpen/screenshots/air/system-tray.png" alt="" /> <div style="font-size: 10px; text-align: center; width: 200px; margin: 5px">Simple Tasks in the System Tray</div></div><p><strong>音效</strong><br /> AIR支持播放音效，Ext.air.Sound的用法甚至更简单了。</p><p>&nbsp;</p><div class="wp_syntax"><div class="code"><pre class="javascript">Ext.<span style="color: #222222">air</span>.<span style="color: #222222">Sound</span>.<span style="color: #222222">play</span><span style="color: #222222">(</span><span style="background-color: #e7e8ec; color: #008080">'beep.mp3'</span><span style="color: #222222">)</span>;</pre></div></div><div style="padding: 20px"><img src="http://extjs.com/playpen/screenshots/air/reminder.png" alt="" /> <div style="font-size: 10px; text-align: center; width: 410px; margin: 5px">The irritating beeping sound is sure to catch your attention</div></div><h3>Ext制定的组件</h3><p>如上文述，整个SimpleTask的程序包含了几个示范的EXT自定义组件。其中一部分是为了复用而专门设计的，未来发布的版本或许会成为标准的组件或示例。</p><p>&nbsp;</p><p><strong>ListTree</strong><br /> &nbsp;&nbsp;&nbsp; ListTree与 ComboBox或SelectBox相类似，不同在于出现的是一块Ext TreePanel面板。比起普通的垂直列表更能清晰显示各层次的列表。<br />&nbsp;&nbsp; &nbsp;伴随着这个组件另外一个酷的功能是制定的选区模型&ldquo;ActivationModel&rdquo;。顾名思义，它以两种形式出现（activation活动选区和记录选区selection），在活动选区下，组件支持完整的键盘控制、用键盘展开/闭合， 与标准树选区模型不同，此选区属于动作本身。</p><div style="padding: 20px"><img src="http://extjs.com/playpen/screenshots/air/treelist.png" alt="" /> <div style="font-size: 10px; text-align: center; width: 300px; margin: 5px">TreeList supports selection of data organized hierarchically</div></div><p><strong>自定义Gird列</strong><br /> 截屏图片可第一时间解释清楚。</p><div style="padding-top: 20px; padding-right: 0pt; padding-bottom: 20px; padding-left: 0pt"><div style="width: 320px; float: left"><img src="http://extjs.com/playpen/screenshots/air/column1.png" alt="" /> <div style="font-size: 10px; text-align: center; margin: 5px">Pseudo button column, used to toggle complete/active</div></div><div style="width: 320px; float: left"><img src="http://extjs.com/playpen/screenshots/air/column2.png" alt="" /> <div style="font-size: 10px; text-align: center; margin: 5px">Menu column, used to set quick reminders</div></div></div><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p><span style="font-weight: 700">Siwthc按钮</span></p><p> 有一种类似radio按钮（单选按钮）的组件好像在桌面的应用程序上经常看得到。这儿就叫作&ldquo;Switch&rdquo;按钮，以便不会与标准HTML的radio按钮出现混淆。它的作用是：提供一组的按钮，同时&ldquo;被按下&rdquo;的只能是一个。</p><div style="padding: 20px"><img src="http://extjs.com/playpen/screenshots/air/switch.png" alt="" /> <div style="font-size: 10px; text-align: center; width: 150px; margin: 5px">Quick view change</div></div><p><strong>总结</strong></p><p>无论是AIR本身的功能还是EXT的扩展，这些都可以在Simple Tasks v2的程序源码中找到真正应用的地方。如果你正在使用着Ext，那么我推荐浏览这些源码。<br />&nbsp;&nbsp;&nbsp; －完整的源码可以在Ext 2.02的<a href="http://extjs.com/download">发布版本</a>中的air/samples/tasks找到。<br />&nbsp;&nbsp;&nbsp; －Adobe AIR 1.0 <a href="http://get.adobe.com/air/">下载</a><br />&nbsp;&nbsp;&nbsp; －Simple Tasks v2 面向AIR的版本 <a href="http://extjs.com/playpen/STasks2.air">下载</a><br />&nbsp;&nbsp;&nbsp; －有关Simple Tasks首个版本可查阅<a href="http://extjs.com/blog/2007/06/29/building-a-desktop-application-with-ext-air-aptana-and-red-bull/">上次的博文</a>。 </p><p>&nbsp;</p><p>作者：<span class="date-header">Jack Slocum</span> </p>
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/165579#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Feb 2008 21:41:47 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/165579</link>
        <guid>http://sp42.javaeye.com/blog/165579</guid>
      </item>
      <item>
        <title>组件的管理与XType</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/162944" style="color:red;">http://sp42.javaeye.com/blog/162944</a>&nbsp;
          发表时间: 2008年02月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          早在Ext 1.x的时候就有Ext.ComponentMgr这个类了，但那时仅是一个雏形，到Ext 2.0的时侯才作为重要的成员，参与到组件的对象模型中。<br /><br />      Ext将页面中的组件的创建、渲染和销毁抽象成为组件的对象模型。全部的组件均支持延时渲染（lazy.rendering）即有需要的情况才会真正地渲染。<br /><br />      在加载JS文件时，也就是定义类的时候，每个主要的组件类如：GridPanel、Panel和DataView都会把自己注册登记到组件管理器中（Component Manager）。注册登记的那个名字叫做“xtype”。<br /><br />      浏览2.0例子的代码你或许会发现就有“xtype”的配置项。XType配置项代表着这个对象属于哪个组件类型，而到时（渲染时）就会调用相关的构造器（constructor）。整个过程无须手工调控，均由ComponentMgr对象内部控制。总得来说，用字面化对象（object literal）的方式定义了一个组件实例的功能，不失为一种便捷的做法（handy shortcut）。<br /><br />      另外你只要在服务端生成JSON便可动态加载这些组件。由于Ext为全体组件提供注册登记的维护，我们可方便地使用Ext.getCmp（COMPONENTID）来访问页面上任意一个组件，这样的好处是不要考虑这些组件实例之引用所在的位置，就可各组件间相互操作。譬如，我们需要从Window的实例中获取GridPanel的引用，你可以从组件管理器中获取组件的引用，免于查找那个Window实例的变量。<br /><br />      虽然Ext.getCmp看起来优点不少，但我建议你谨慎使用和避免过于滥用。事因这样会强制将几个语义上不同的几个类捆绑在一起，组合成一个比较“笼统”的类。如在标准的面向对象的实践中或实现一个观察者模式的时候，采用Ext.getCmp作为一种设计的方案就不太适宜了。
          <br/>
          <span style="color:red;">
            <a href="http://sp42.javaeye.com/blog/162944#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Feb 2008 13:00:51 +0800</pubDate>
        <link>http://sp42.javaeye.com/blog/162944</link>
        <guid>http://sp42.javaeye.com/blog/162944</guid>
      </item>
      <item>
        <title>用Ext编排JavaScript任务</title>
        <author>sp42</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sp42.javaeye.com">sp42</a>&nbsp;
          链接：<a href="http://sp42.javaeye.com/blog/161959" style="color:red;">http://sp42.javaeye.com/blog/161959</a>&nbsp;
          发表时间: 2008年02月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          《用Ext编排JavaScript任务Ext.TaskMgr Scheduling JavaScript Tasks》<br />By Aaron Conran<br />Ext支持版本： 1.x/2.0<br /><br />     Ext.TaskMgr是ExtJS库中一项未归档的功能，允许以可编程的方式编排调度某项任务。你可反复每隔一定时间地运行，也可以指定每个任务运行的次数、运行的持续时间和运行的频率等等。Ext.TaskMgr其实是Ext.TaskRunner的一个实例，它的源码可以source/util/TaskMgr.js找到。<br /><br />    要编排一个任务，你可以按照以下的语句：<br /><pre name="code" class="javascript">Ext.TaskMgr.start({run: myFunction, interval: 1000});</pre><br />    除非关闭浏览器或调用stop方法停止任务，如果不是每一秒就会运行一次名为myFunction的函数。<br /><br />任务的配置项：<br /> * run: 编排的函数<br /> * scope: 执行的作用域<br /> * interval: 运行的频率<br /> * duration: 运行多久<br /> * args: 要传入到编排函数内的参数，缺省下函数所接受到的参数为你任务已运行的次数<br /> * repeat: 任务运行的次数<br /><br