开发指南–浏览器用户界面–选项页面(Options)

选项(Options)

你可能想通过提供一个选项页,来允许用户对你的扩展进行自定义配置。如果这样做,系统会在扩展程序管理页面(chrome://extensions)中提供一个链接指向它。点击选项链接会打开一个新的标签页来指向你的选项页面。

原文 写道
To allow users to customize the behavior of your extension, you may wish to provide an options page. If you do, a link to it will be provided from the extensions management page at chrome://extensions. Clicking the Options link opens a new tab pointing at your options page.

第一步: 在Manifest文件中声明你的选项页面

原文 写道
Step 1: Declare your options page in the manifest

{
  "name": "My extension",
  ...
  "options_page": "options.html",
  ...
}

第二步: 编写你的选项页面

原文 写道
Step 2: Write your options page

这是一个选项页面的例子:

原文 写道
Here is an example options page:

<html>
<head><title>My Test Extension Options</title></head>
<script type="text/javascript">

// 将选项保存到localStorage。
function save_options() {
  var select = document.getElementById("color");
  var color = select.children[select.selectedIndex].value;
  localStorage["favorite_color"] = color;

  // 更新状态,让用户知道选项被保存。
  var status = document.getElementById("status");
  status.innerHTML = "Options Saved.";
  setTimeout(function() {
    status.innerHTML = "";
  }, 750);
}

// 根据localStorage中保存的值恢复选择框的状态。
function restore_options() {
  var favorite = localStorage["favorite_color"];
  if (!favorite) {
    return;
  }
  var select = document.getElementById("color");
  for (var i = 0; i < select.children.length; i++) {
    var child = select.children[i];
    if (child.value == favorite) {
      child.selected = "true";
      break;
    }
  }
}

</script>

<body onload="restore_options()">

Favorite Color:
<select id="color">
 <option value="red">red</option>
 <option value="green">green</option>
 <option value="blue">blue</option>
 <option value="yellow">yellow</option>
</select>

<br>
<button onclick="save_options()">Save</button>
</body>
</html>

重要说明

  • 这个功能在4.0.222.x版本后的某个正式主干版本中加入。
  • 原文 写道
    This feature is checked in to the trunk and should land in official builds sometime after version 4.0.222.x.
  • 我们计划提供一些默认的CSS样式,以使不同扩展的选项页面外观一致。你可以在crbug.com/25317中加星来促进更新。
  • 原文 写道
    We plan on providing some default css styles to encourage a consistent look across different extensions’ options pages. You can star crbug.com/25317 to be notified of updates.

ExtJS笔记–Ext.form.Checkbox

Ext.form.Checkbox

类全称: Ext.form.Checkbox

继承自于: Ext.form.Field

单独的checkbox域,可以直接代替传统checkbox域。 

配置项

1、focusClass : String 

当表单元素获取焦点时的CSS样式(默认为”x-form-focus”)

2、fieldClass : String 

表单元素一般状态CSS样式(默认为”x-form-field”)。

3、checked : Boolean 

如果checkbox需要呈现选中状态,设置checked为True(默认为false)。

4、autoCreate : String/Object 

一个指定的DomHelper配置对象,如果为真则为一个默认对象({tag: “input”, type: “text”, size: “20”, autocomplete: “off”})。

5、boxLabel : String 

checkbox旁边显示的文字。

6、inputValue : String 

应该显示在元素value处的值。 

7、fieldLabel : String 

在组件旁边那里显示的label文本(默认为”)。

此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。 

8、inputType : String 

input字段的type属性,诸如 radio、text、password、file等的元素都有type属性。属性是“file”与“pssword”就要在这里设置了,因为当前Ext并没有这些单独的组件。 注意当你使用inputType:’file’时,#emptyText就避免使用。

9、tabIndex : Number 

字段的tabIndex。注意这只对已渲染的元素有效,applyTo的那些无效(默认为undfined)。

10、value : Mixed 

字段初始化的值(默认为undefined)。

11、name : String 

字段的name属性,HTML的name属性(默认为”)。 

12、cls : String 

一个可选添加的CSS样式类,加入到组件的元素上(默认为”)。这为组件或组件的子节点加入标准CSS规则提供了方便。

13、invalidClass : String 

当出现无效字段所使用上的CSS样式(默认为”x-form-invalid)。 

14、invalidText : String 

表单元素无效时标在上面的文本信息(默认为”The value in this field is invalid”)。

15、validationEvent : String/Boolean 

初始化元素验证的事件名,如果设假,则不进行验证(默认”keyup”)。

16、validateOnBlur : Boolean 

是否当失去焦点时验证此表单元素(默认真)。 

17、validationDelay : Number 

用户输入开始到验证开始的间隔毫秒数(默认250毫秒)。

18、msgTarget : String 

错误提示的显示位置。 可以是以下列表中的任意一项(默认为”qtip”)

19、msgFx : String 

Experimental 表单元素无效提示显示的动画效果(默认为”normal”)

20、readOnly : Boolean 

如果为真,则在HTML时标明此表单元素为只读 — 注意:只是设置表单对象的只读属性。 

21、disabled : Boolean 

渲染该组件为禁用状态的(默认为false)。

22、x : Number 

如果该组件是在一个定位的组件之中,可通过该属性返回组件的x本地(左边)坐标。

23、y : Number 

如果该组件是在一个定位的组件之中,可通过该属性返回组件的y本地(顶部)坐标。

24、pageX : Number 

如果该组件是在一个定位的组件之中,可通过该属性返回组件的x页面坐标。 

25、pageY : Number 

如果该组件是在一个定位的组件之中,可通过该属性返回组件的y页面坐标。

26、height : Number 

此组件的高度(单位象素)(缺省为auto)。 

27、width : Number 

此组件的宽度(单位象素)(缺省为auto)。 

28、autoHeight : Boolean 

True表示为使用height:’auto’,false表示为使用固定高度(缺省为false)。 注意:尽管许多组件都会继承该配置选项,但是不是全部的’auto’ height都有效。 autoHeight:true的设定表示会依照元素内容自适应大小,Ext就不会过问高度的问题。

29、autoWidth : Boolean 

True表示为使用width:’auto’,false表示为使用固定宽度(缺省为false)。 注意:尽管许多组件都会继承该配置选项,但是不是全部的’auto’ width都有效。 autoWidth:true的设定表示会依照元素内容自适应大小,Ext就不会过问宽度的问题。

30、labelStyle : String 

关于表单字段的label提示文本的CSS样式的“完全表达式(CSS style specification)”。默认为””,若容器的lableStyle有设置这样设置值。 此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。

31、labelSeparator : String 

分隔符,就是每行表单中的label文本显示后面紧接着的那个分隔符(默认值是Ext.layout.FormLayout#labelSeparator,即缺省是分号“:”)。 如果指定空白字符串””就表示不显示所谓的“分隔符”。此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。 

32、hideLabel : Boolean 

True表示为完全隐藏label元素。默认下,即使你不指定fieldLabel都会有一个空白符插入,好让支撑field为一行。 设该值为true就不会有这个空白符了。 此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。 

33、clearCls : String 

关于field的清除样式(默认为“x-form-clear-left”)。此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。 

34、itemCls : String 

关于容器的表单项元素的额外的CSS样式(默认为””,如容器的itemCls有设置的话就用那个值)。由于该样式是作用于整个条目容器的,这就会对在内的表单字段、label元素(若有指定)或其他元素只要属于条目内的元素都有效。 此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。

35、id : String 

唯一的组件id(默认为自动分配的id)。 出于你打算用id来获取组件引用这一目的(像使用Ext.ComponentMgr#getCmp的情形),你就会送入一个你写好的id到这个方法。 提示:容器的元素即HTML元素也会使用该id渲染在页面上。如此一来你就可以采用CSS id匹配的规则来定义该组件的样式。 换句话说,实例化该组件时,送入不同的Id,就有对应不同的样式效果。

36、xtype : String 

用于登记一个xtype。 

37、overCls : String 

关于鼠标上移至该组件元素的CSS样式类,移出时撤销该样式的效果(默认为”)。该配置项在处理元素”active”或”hover”的时候很有用。 

38、style : String 

作用在组件元素上特定的样式。该值的有效格式应如Ext.Element#applyStyles。 

39、ctCls : String 

一个可选添加的CSS样式类,加入到组件的容器上(默认为”)。这为容器或容器的子节点加入标准CSS规则提供了方便。 An optional extra CSS class that will be added to this component’s container (defaults to ”). 

40、hidden : Boolean 

渲染该组件为隐藏状态的(默认为false)。 

41、plugins : Object/Array 

针对该组件自定义的功能,是对象或这些对象组成的数组。一个有效的插件须保证带有一个init的方法以便接收属于Ext.Component类型的引用。当一个组件被创建后,若发现由插件可用,组件会调用每个插件上的init方法,传入一个应用到插件本身。这样,插件便能按照组件所提供的功能,调用到组件的方法或响应事件。

42、applyTo : Mixed 

节点的id,或是DOM节点,又或者是与DIV相当的现有元素,这些都是文档中已经存在的元素当使用applyTo后,主元素所指定的id或CSS样式类将会作用于组件构成的部分,而被创建的组件将会尝试着根据这些markup构建它的子组件。使用了这项配置后,不需要执行render()的方法。 若指定了applyTo,那么任何由#renderTo传入的值将会被忽略并使用目标元素的父级元素作为组件的容器。

43、renderTo : Mixed 

容器渲染的那个节点的id,或是DOM节点,又或者是与DIV相当的现有元素。 使用了这项配置后,不需要执行render()的方法。

44、stateful : Boolean 

组件记忆了一个状态信息,启动时候就根据这个标记获取状态信息。 组件必须设置其#stateId或#id,较有保障性, 而自动生成的id在跨页面加载的时候则不能保证一定不出现相同的情形。为了能记忆状态,必须通过方法设置一个Ext.state.Provider的实例置于一个状态管理器之中, 然后才可以用Ext.state.Provider#set set与Ext.state.Provider#get get的方法,保存记忆和提取记忆。 可用内建的Ext.state.CookieProvider实现设置一个。 

45、stateId : String 

出于状态管理目的id,(默认是人为设置过的组件id,如果组件是自动生成的id那种那么该项是null。

46、autoEl : Mixed 

某种标签的字符串或者Ext.DomHelper DomHelper配置对象,用于创建承载此组件的元素。一般而言你无须对其设置。对于这些基础类而言,就会使用div作为其默认的元素。 Ext类写得越复杂,组件的onRender方法产生的DOM结构就随之更为复杂。 该项是为创建形形色色的DOM元素而准备的,开发者可根据程序的特定要求去制定,

47、disabledClass : String 

当组件被禁用时作用的CSS样式类(默认为”x-item-disabled”)。

48、allowDomMove : Boolean 

当渲染进行时能否移动Dom节点上的组件(默认为true)。

49、autoShow : Boolean 

True表示为在渲染的时候先检测一下有否关于隐藏的样式类(如:’x-hidden’或’x-hide-display’),有就移除隐藏的样式类(缺省为false)。

50、hideMode : String 

这个组件是怎么隐藏的。可支持的值有”visibility” (css中的visibility),”offsets”(负偏移位置)和”display”(css中的display)-默认为“display”。 容器可能是{@link Ext.layout.CardLayout card layout}或Ext.TabPanel TabPanel中的一员,会有隐藏/显未的情形,这种情形下最好将其hideMode模式设为”offsets”。这保证了计算布局时,组件仍有正确的高度和宽度,组件管理器才能顺利地测量。

51、hideParent : Boolean 

True表示为当隐藏/显示组件时对组件的容器亦一同隐藏/显示,false就只会隐藏/显示组件本身(默认为false)。例如,可设置一个hide:true的隐藏按钮在window,如果按下就通知其父容器一起隐藏,这样做起来比较快捷省事。

<!–EndFragment–>

MoinMoin的基本用法

注册和修改用户配置

用户注册完毕需要点击’清除此提示信息’链接, 否则可能不能成功注册.

用户的配置文件在moin-desktop\wiki\data\user目录下, 以纯文本方式保存, 可以手工修改.

修改网站名称

在moin-desktop/wikiconfig.py中, 修改:

 
  1. class Config(DefaultConfig):  
  2.     sitename = u“Marshal\u7684\u77E5\u8BC6\u7BA1\u7406”  

如果是中文,需要通过\u的编码转换。

以上内容前加u”…”, 表示是unicode编码, ‘\u7684\u77E5\u8BC6\u7BA1\u7406’是中文的知识管理, 需要自行解决,比如使用java的native2ascii

修改提交次数的限制

wikiconfig.py中, 增加:

 
  1. class Config(DefaultConfig):  
  2. …  
  3.     surge_action_limits = { ‘default’: (100, 1) } # max. 100 requests in 1 second  
  4.     surge_lockout_time = 60 # secs you get locked out when you ignore warnings  
  5. …  

以上配置提交的限制, 默认情况下提交多次后会提示要间隔一段时间才能再提交.

本地化配置

系统页面和帮助的中文化

访问: localhost:wiki_port/SystemPagesSetup, 其中wiki_port是moinmoin的端口号, 如果没有自行配置, 默认是8080.

在SimplifiedChinese.zip行上, 点击’安装‘链接即可, 这时moinmoin的界面和帮助已经中文化.

时区的修改

moinmoin默认使用格林威治标准时间, 国内市区是东8区, 比标准时间早8小时(+8).

如果不修改, 时间戳很别扭.

修改办法, 用户登录后点击’用户设置’链接, 在时区选择….[+08:00]的选项

定制页面风格

我一般选用modern风格, 并在此基础上修改了css样式, 在moin-desktop\wiki\htdocs\modern\css目录下.

定制首页

本人定制首页:

 
  1. ||“100%”>||  
  2. ||<^25%> [[Include(工作文档)]] ||<^30%>  [[Include(生活文档)]] [[BR]] [[Include(学习文档)]]||<^> [[Include(任务导航)]] [[BR]] [[Include(备忘录)]]||  

第一行表示要使用整个浏览器宽度.

第二行是页面的布局, 其中工作文档, 生活文档…都是站内连接

Incluede是moinmoin的宏, 表示包含页面.

具体解释, 参见moinmoin的帮助文档有关宏的部分.

注意事项

尽量使用英文文件和目录名称, 中文文件名有时因为编码过长而出错

ExtJs总结(二)

Ext.onready()是用于在页面完成加载后显示内容,如果希望在加载过程中显示某些内容,那么必须在
<body>
    <div id=”test”>要显示Ext组件的块</div>
    <script type=”text/javascript” src=”包含Ext组件的代码”></script>
</body>
Ext.Panel是一个容器组件,显示为面板。相关属性如下
:
    var panel = new Ext.Panel({
        el: ‘demo’,        //用于指定显示的位置,作用与renderTo类似,但用这个属性必须在后面配置render()方法,而renderTo不需要
        title: ‘测试标题’,    //标题
        floating: true,        //浮动
        shadow: true,        //阴影
        draggable: true,    //可拖动
        collapsible: true,    //可收缩
        html: ‘测试内容’,    //面板内容
        pageX: 100,        //位置
        pageY: 50,
        width: 200,        //大小
        height: 150
    });

fireFox的调试工具firebug,
ie的调试工具debugbar 与companio.js

安装firebug
工具–>附加组件
f12 打开调试窗口 或ctrl+f12 弹出调试窗口

开启调试功能,注意不要对所有的网站开启调试功能,这样会引起浏览器崩溃,因为有些网站采用了旧的ie特有写法,会导致firefox不停报错。
通过选择“控制台”,“脚本”,“网络”下按按钮中的站点来设定针对哪些站点开启调试功能。

布局
1.容器有哪些?
容器可以通过
layout指定布局管理器
items指定需要摆放的组件。

2.布局管理器有哪些

FitLayout可以自动根据容器大小填充,但其中items只能指定一个组件,不能指定多个,而且组件不能指定自动调整高度autoHeight:true。

BorderLayout
可以针对多个子组件进行布局,弥补了FitLayout的不足。可以针对上、下、左、右、中五个方位进行布局。其中center必须指定,其余可以省略。
上、下只能指定高度,左、右只能指定宽度,中间部分自动计算。
同样也要避免指定autoHeight:true,以免破坏了布局。

上、下、左、右可以指定split:true进行调整大小,同时指定minSize和maxSize对调整范围进行限制。

每个区域都可以通过设置title:标题,collapsible:true来实现显示内容的折叠。

AccordionLayout实现伸缩菜单的布局
设置layout:’accordion’后,要记得在items的每个元素里都要加上title参数,因为accordion是通过点击标题来伸缩显示。另外与布局相关的配置参数都写到layoutConfig:{
  titleCollapse:true, 是否单击标题折叠子面板
  animate:true, 展开和折叠是否使用动画效果
  activeOnTop:展开和折叠时是否改变子面板顺序
}

CardLayout制作向导最合适。
CardLayout配置几个子面板,每次它只显示其中一个。

当前显示的子面板是由activeItem来控制的。

AnchorLayout
可以为items中的每个组件指定与总体布局大小的值
第一种方式使用百分比进行配置,设置一个子组件占整体长和宽的百分比。
layout:’anchor’,
items:[{

anchor:”宽度百分比 高度百分比”
},{

}];

第二种方式为设置右侧与底部的边距。

layout:’anchor’,
items:[{

anchor:”-右侧的像素值 -底部的像素值”
},{

}];
以上两种方式可以同时使用。

AbsoluteLayout
是AnchorLayout的扩展,具备AnchorLayout所有特性,AnchorLayout布局下的子组件都是自上而下竖直排列的,我们不能控制每个组件的位置,AbsoluteLayout正是为解决这个问题而来的。
我们通过x,y参数达到控制子组件位置的效果。

FormLayout表单专用布局管理器
它也是AnchorLayout的扩展。
Ext.form.FormPanel使用它作为默认的布局方式。它提供了一素列的参数来控制显示效果。
FormLayout提供的用于控制表单显示的参数
hideLabels:是否隐藏field的标签
itemCls:表单显示的样式
labelAlign:标签的对齐方式(左,中,右)
labelPad:标签空白的像素值
labelWidth:标签宽度

Ext.form.Field对应的参数
clearCls:消除div渲染的css样式
fieldLabel:对应field的标签内容
hideLabel:是否隐藏标签
itemCls:field的css样式
labelSeparator:标签和field之间的分隔,默认是:
labelStyle: 标签的CSS样式

ColumnLayout布局

layout:’column’,
items:[{
    title:’column 1′,
    columnWidth: .3
},{
    title:’column 2′,
    columnWidth: .7
}]
注意columnWidth参数,它是0-1之间的一个小数,表示组件在整体中所占的百分比,它们的总和应该是1.
如果希望某列的宽度固定,则可以直接用width:像素 指定。而其余的列会进行宽度的自动配置。

Ext.Container是所有可布局组件的超类,只要是继承了Ext.Contrainer的子类就可以对自身进行布局。最常用的也是最主要的参数layout和items,它们分别用来设置使用的布局方式和包含的子组件。只要是进行布局,就必然会用到这两个参数,与这两个参数对应的还有另外两个参数,它们在需要进行特殊配置时非常有用:layoutConfig用于完成特殊配置,activeItem表示当前显示哪一个子组件,这在AccordionLayout和CardLayout等每次只能显示一个子组件的布局方式中非常有用。
重点提及的一个参数是defaultType,它用来设置子组件默认使用的xtype的值。默认情况下是defaultType:’panel’也就是items中创建的每个子组件都是Ext.Panel的实例。

可以使用Viewport对整个页面进行布局,但是每个页面只能有一个Viewport的限制。

远程发布的设计和实现

远程发布的设计和实现

 

在实施门户部署时,部分客户会有内外网都要的需求,即内容信息维护在内网完成,内网用户可以通过内网直接访问门户,但同时需要加门户发布到外网,供Internet上用户访问,内外网的信息需要保持同步。

第一步需要将动态的门户页面全部发布成静态html页面(可参考我的另外一篇日志《门户站点静态发布的设计与实现》,访问地址:http://infinite.iteye.com/blog/390687);

第二步还需要将第一步发布出来的静态html页面以及相关的图片、jscss文件等远超发布到外网服务器,同时外网访问出于性能考虑,可能需要做负载均衡,还需要远超发布时能支持发布至多台外网服务器上。

以下具体讲述下第二步远程发布的设计思路和具体实现。主要将借助开源组织apachecommon-net.jar包的FTPClient类。

 

一、             编写远超发布配置信息文件

 

配置信息需要包含有外网服务器的ftp访问地址、用户名、密码,以及内网服务器需要上传至外网服务器的目录信息。格式如下:

 

<ftpServer url=”192.168.0.31″ userName=”root” password=”password”>

<filePath localDir=”d:/。。。/webapp/html” remoteDir=”temp/html”/>

<filePath localDir=”d:/ 。。。/webapp/core” remoteDir=”temp/core”/>

<filePath localDir=”d:/ 。。。/webapp/model” remoteDir=”temp/model”/>

<filter-pattern>index,articleList</filter-pattern>

</ftpServer>

 

二、             解析配置文件,创建FTP连接

 

根据上面配置文件ftpServer的信息,可创建一个FTPClient连接。代码参考如下:

 

private void connect2FtpServer(String url, String user, String pwd) throws SocketException, IOException {

        this.ftp = new FTPClient();

        ftp.connect(url);

        ftp.login(user, pwd);

        int reply = ftp.getReplyCode();

        if (!FTPReply.isPositiveCompletion(reply)) {

            ftp.disconnect();

        }

        this.remoteRoot = ftp.printWorkingDirectory();

}

 

三、             上传文件(夹)

创建了FTP连接后,就可以利用该连接进行文件的ftp上传操作。这里有几点需要注意:

1、按本地上传的文件夹的目录结构,在外网服务器上对应的文件夹下创建一模一样的目录结构。

/**

  *  在上传文件夹的过程中,如果服务器的目标目录中和上传文件夹的目录有区别 则创建各级目录。

* @param remoteDir

* @param relativePath

*/

private void makeDirectory(String remoteDir, String relativePath) {

   try {

       ftp.changeWorkingDirectory(this.remoteRoot); // 先切换到根目录下

            relativePath = remoteDir + “/” + relativePath;

            String[] dir = relativePath.split(“/”);// 目录分级

            for (int i = 0; i < dir.length; i++) {

               if (!ftp.changeWorkingDirectory(dir[i])) {// 是否有子目录dir[i]

                    ftp.makeDirectory(dir[i]);

               }

               ftp]);.changeWorkingDirectory(dir[i

            }

     } catch (Exception e) {

          log.error(ftp服务器上创建相应目录时候出错, e);

     }

}

 

2、过滤掉无需重复上传的文件。如何过滤规则可以根据需要制定。比如,配置文件里可加入<filter-pattern>index,articleList</filter-pattern>的匹配配置,表示文件名包含index或者articleList字样的文件每次都要上传;还可以根据文件的最后修改时间来判断是否需要上传该文件(比如三小时内修改过的文件上传,其余不上传,可结合第四步的定时机制)。

 

指定好了上传目录,上传文件很简单,只需简单的调用FTPClinetstoreFile方法。可参考下面代码:

String fileName = file.getName(); // 本地文件名

FileInputStream input = new FileInputStream(file);

ftp.storeFile(fileName, input);

 

四、             定时远程发布到外网服务器

通过上面三个步骤,已经可以将内网服务器的文件顺利发布至外网服务器,但是我们还是需要做一定的优化。

首先什么时候触发远程发布。为了保证内外网信息实时同步,最理想的方式就是内网内容一更新,即触发远程发布,将更新内容发布至外网服务器。但这样导致的性能问题非常严重。因为存在多个内容维护的管理员,可能每个人都在做远程发布,这就需要多个ftp连接,非常耗费资源,且相互间还会影响彼此的上传速度。

针对上面问题,使用定时远程发布可以带来比较好的性能提升。这需要在本地(即内网服务器)上创建一个守护进程,由它不停的检测本地需要上传的目录,发现有更新且到达定时时间(比如15分钟),则启动远程发布。否则不启动。这样可保证始终只有一个ftp连接,多个管理员同时更新内容不会相互影响彼此上传速度。只不过这样一定程度上了牺牲内容的实时更新(会稍微有所延迟)。

FLEX实践:TREE与SWFLOADER的简单应用

<!–[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning />
<w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:SpaceForUL />
<w:BalanceSingleByteDoubleByteWidth />
<w:DoNotLeaveBackslashAlone />
<w:ULTrailSpace />
<w:DoNotExpandShiftReturn />
<w:AdjustLineHeightInTable />
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
<w:UseFELayout />
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]–><!–[if gte mso 9]><xml>
<w:LatentStyles DefLockedState=”false” LatentStyleCount=”156″>
</w:LatentStyles>
</xml><![endif]–><!–
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-alt:SimSun;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
@font-face
{font-family:”\@宋体”;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:””;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
mso-pagination:none;
font-size:10.5pt;
mso-bidi-font-size:12.0pt;
font-family:”Times New Roman”;
mso-fareast-font-family:宋体;
mso-font-kerning:1.0pt;}
p
{mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:0cm;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:宋体;
mso-bidi-font-family:宋体;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
–><!–[if gte mso 10]>
<mce:style><!
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:””;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:”Times New Roman”;
mso-fareast-font-family:”Times New Roman”;
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
–>
<!–[endif]–>

前言:在开始之前,先描述一下这例子的内容

1)实现TREE控件的简单应用(加载内容为XML格式)

2)外部CSS应用

3)不同FLEX应用程序之间通过SWFLOADER调用

下面开始本次实践吧!

1)创建CSS文件
CssTest.css

/*
CSS file */

.MyTextStyle1
{
font-family:
Copacetix;
font-size:
15pt;

fontWeight:bold;

color:#B62F19;

cornerRadius:13;
width:104;
height:32;
alpha:0.49;
}

2)创建CssTest.mxml(调用CSS文件为其中的button控件做外观设置)

< xml
version=”1.0″ encoding=”utf-8″ >
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”absolute”>
<mx:Style source=”
CssTest.css” />
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function showName():void{
Alert.show(“Your name
is: “+username.text);
}
]]>
</mx:Script>
<mx:Text styleName=”MyTextStyle” text=”Please
input your name:” width=”305″ x=”63″
y=”37″/>
<mx:Button x=”120″ y=”165″
label=”Show Name” styleName=”MyTextStyle1″
click=”showName()”/>
<mx:TextInput x=”63″ y=”92″
width=”228″ height=”32″ fontSize=”15″
color=”#100B3C” id=”username” />

</mx:Application>

3)创建TreeTest2.mxml(引用TREE控件并调用CssTest.mxml

< xml
version=”1.0″ encoding=”utf-8″ >
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”absolute”>
<mx:Style source=”CssTest.css” />
<mx:states>
<mx:State
name=”show1″>

<mx:SetStyle target=”{panel1}” name=”fontSize”
value=”26″/>

<mx:SetStyle target=”{panel1}” name=”verticalAlign”
value=”top”/>

<mx:SetProperty target=”{panel1}” name=”layout”
value=”vertical”/>

<mx:AddChild position=”lastChild”>

<mx:SWFLoader x=”409″ y=”76″
source=”CssTest.swf”/>

</mx:AddChild>
</mx:State>
</mx:states>
<mx:XMLList id=”treeData”>
<node id=”10000″ label=”评估计划“>
<node
id=”10100″ label=”
计划生成器“>

<node id=”10101″ label=”新建计划
canvas=”javaest.FirstCanvas”/>

<node id=”10102″ label=”复制计划
canvas=”javaest.SecondCanvas”/>

</node>

<node
id=”10200″ label=”计划管理“>

<node id=”10201″ label=”将计划转为准备运行” canvas=”javaest.GetProductList”/>

<node id=”10202″ label=”将计划转为正在配置” canvas=”javaest.SecondCanvas”/>

<node id=”10203″ label=”查询计划状态
canvas=”javaest.FirstCanvas”/>

</node>
<node
id=”10300″ label=”我的博客“>

<node id=”10301″ label=”北边村人
canvas=”javaest.iteye.com”/>

</node>
</node>
</mx:XMLList>
<mx:Script>
<![CDATA[

import mx.controls.Image;
import
mx.controls.Button;

import mx.containers.Canvas;

import mx.controls.Alert;

private function addNewTabPage(event:Event):void {

var selectedNode:XML=Tree(event.target).selectedItem as XML;

var id:String=selectedNode.@id;

var label:String=selectedNode.@label;

var canvasClassName:String=selectedNode.@canvas;

if (functionTree.dataDescriptor.isBranch(selectedNode)) {

functionTree.expandItem(selectedNode,
!functionTree.isItemOpen(selectedNode));

} else{

//如果节点项为新建计划”,则将页面切换到SHOW1状态下

if(label==”新建计划“){

currentState=”show1″ ;

}

}

Tree(event.target).selectedItem=null;

}

]]>
</mx:Script>
<mx:Panel width=”197″
height=”548″ dropShadowEnabled=”false” title=”新闻管理” id=”panel1″ fontSize=”26″>
<mx:Tree
id=”functionTree” change=”addNewTabPage(event)”
width=”171″ height=”100%” enabled=”true”
showRoot=”true” dataProvider=”{treeData}”
labelField=”@label” borderStyle=”none”
fontSize=”13″>
</mx:Tree>
</mx:Panel>
</mx:Application>

运行结果:

当节点不为新建计划时,不显示SHOW1的内容

当点击“新建计划”时,显示SHOW1状态的内容

运行CssTest.mxml的内容

Ext.form.FormPanel

1、layout : String 

此容器所使用的布局类型。如不指定,则使用缺省的Ext.layout.ContainerLayout类型。 当中有效的值可以是:accordion、anchor、border、cavd、column、fit、form和table。 针对所选择布局类型,可指定#layoutConfig进一步配置。

 

2、layoutConfig : Object 

选定好layout布局后,其相应的配置属性就在这个对象上进行设置。 (即与#layout配置联合使用)有关不同类型布局有效的完整配置信息,参阅对应的布局类:

Ext.layout.Absolute 

Ext.layout.Accordion 

Ext.layout.AnchorLayout 

Ext.layout.BorderLayout 

Ext.layout.CardLayout 

Ext.layout.ColumnLayout 

Ext.layout.FitLayout 

Ext.layout.FormLayout 

Ext.layout.TableLayout

 

3、bufferResize : Boolean/Number 

当设置为true(100毫秒)或输入一个毫秒数,为此容器所分配的布局会缓冲其计算的频率和缓冲组件的重新布局。如容器包含大量的子组件或这样重型容器,在频繁进行高开销的布局时,该项尤为有用。

 

4、activeItem : String/Number 

组件id的字符串,或组件的索引,用于在容器布局渲染时候的设置为活动。例如,activeItem: ‘item-1’或activeItem: 0 index 0 = 容器集合中的第一项)。只有某些风格的布局可设置activeItem(如Ext.layout.Accordion、Ext.layout.CardLayout和 Ext.layout.FitLayout),以在某个时刻中显示一项内容。相关内容请参阅Ext.layout.ContainerLayout#activeItem。 

 

5、items : Mixed 

一个单独项,或子组件组成的数组,加入到此容器中。 每一项的对象类型是基于Ext.Component的

你可传入一个组件的配置对象即是lazy-rendering的做法,这样做的好处是组件不会立即渲染,减低直接构建组件对象带来的开销。 要发挥”lazy instantiation延时初始化”的特性,应对组件所属的登记类型的Ext.Component#xtype属性进行配置。

 

要了解所有可用的xtyps,可参阅Ext.Component。如传入的单独一个项,应直接传入一个对象的引用( 如items: {…})。多个项应以数组的类型传入(如items: [{…}, {…}])。

 

6、defaults : Object 

应用在全体组件上的配置项对象,无论组件是由#items指定,抑或是通过#add、#insert的方法加入,都可支持。 缺省的配置可以是任意多个容器能识别的“名称/值”, 假设要自动为每一个Ext.Panel项设置padding内补丁,你可以传入defaults: {bodyStyle:’padding:15px’}。

 

7、autoDestroy : Boolean 

若为true容器会自动销毁容器下面全部的组件,否则的话必须手动执行销毁过程(默认为true)。 

 

8、hideBorders : Boolean 

True表示为隐藏容器下每个组件的边框,false表示保留组件现有的边框设置(默认为false)。

 

9、defaultType : String 

容器的默认类型,用于在Ext.ComponentMgr中表示它的对象。(默认为’panel’)

 

10、x : Number 

如果该组件是在一个定位的组件之中,可通过该属性返回组件的x本地(左边)坐标。 

 

11、y : Number 

如果该组件是在一个定位的组件之中,可通过该属性返回组件的y本地(顶部)坐标。 

 

12、pageX : Number 

如果该组件是在一个定位的组件之中,可通过该属性返回组件的x页面坐标。 

 

13、pageY : Number 

如果该组件是在一个定位的组件之中,可通过该属性返回组件的y页面坐标。 

 

14、height : Number 

此组件的高度(单位象素)(缺省为auto)。

 

15、width : Number 

此组件的宽度(单位象素)(缺省为auto)。 

 

16、autoWidth : Boolean 

True表示为使用width:’auto’,false表示为使用固定宽度(缺省为false)。 注意:尽管许多组件都会继承该配置选项,但是不是全部的’auto’ width都有效。 autoWidth:true的设定表示会依照元素内容自适应大小,Ext就不会过问宽度的问题。 

 

17、fieldLabel : String 

在组件旁边那里显示的label文本(默认为”)。 

此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。 

 

18、labelStyle : String 

关于表单字段的label提示文本的CSS样式的“完全表达式(CSS style specification)”。默认为””,若容器的lableStyle有设置这样设置值。

此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。                      

 

19、labelSeparator : String 

分隔符,就是每行表单中的label文本显示后面紧接着的那个分隔符(默认值是Ext.layout.FormLayout#labelSeparator,即缺省是分号“:”)。 如果指定空白字符串””就表示不显示所谓的“分隔符”。

此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。 

 

20、hideLabel : Boolean 

True表示为完全隐藏label元素。默认下,即使你不指定fieldLabel都会有一个空白符插入,好让支撑field为一行。 设该值为true就不会有这个空白符了。 

此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。 

 

21、clearCls : String 

关于field的清除样式(默认为“x-form-clear-left”)。

此组件只有在Ext.form.FormLayout FormLayout布局管理器控制的容器下渲染才有用。

 

22、id : String  

唯一的组件id(默认为自动分配的id)。 出于你打算用id来获取组件引用这一目的(像使用Ext.ComponentMgr#getCmp的情形),你就会送入一个你写好的id到这个方法。 提示:容器的元素即HTML元素也会使用该id渲染在页面上。如此一来你就可以采用CSS id匹配的规则来定义该组件的样式。 换句话说,实例化该组件时,送入不同的Id,就有对应不同的样式效果。

 

23、xtype : String 

用于登记一个xtype。

 

24、cls : String 

一个可选添加的CSS样式类,加入到组件的元素上(默认为”)。这为组件或组件的子节点加入标准CSS规则提供了方便。

 

25、overCls : String 

关于鼠标上移至该组件元素的CSS样式类,移出时撤销该样式的效果(默认为”)。该配置项在处理元素”active”或”hover”的时候很有用。 

 

26、style : String 

作用在组件元素上特定的样式。该值的有效格式应如Ext.Element#applyStyles。 

 

27、ctCls : String 

一个可选添加的CSS样式类,加入到组件的容器上(默认为”)。这为容器或容器的子节点加入标准CSS规则提供了方便。

 

28、hidden : Boolean 

渲染该组件为隐藏状态的(默认为false)

 

29、plugins : Object/Array 

针对该组件自定义的功能,是对象或这些对象组成的数组。一个有效的插件须保证带有一个init的方法以便接收属于Ext.Component类型的引用。当一个组件被创建后,若发现由插件可用,组件会调用每个插件上的init方法,传入一个应用到插件本身。这样,插件便能按照组件所提供的功能,调用到组件的方法或响应事件。 

 

30、renderTo : Mixed 

容器渲染的那个节点的id,或是DOM节点,又或者是与DIV相当的现有元素。 使用了这项配置后,不需要执行render()的方法。

 

31、stateful : Boolean 

组件记忆了一个状态信息,启动时候就根据这个标记获取状态信息。 组件必须设置其#stateId或#id,较有保障性, 而自动生成的id在跨页面加载的时候则不能保证一定不出现相同的情形。

为了能记忆状态,必须通过方法设置一个Ext.state.Provider的实例置于一个状态管理器之中, 然后才可以用Ext.state.Provider#set set与Ext.state.Provider#get get的方法,保存记忆和提取记忆。 可用内建的Ext.state.CookieProvider实现设置一个。

 

要设置页面的状态供应器: To set the state provider for the current page: 

 

32、stateId : String 

出于状态管理目的id,(默认是人为设置过的组件id,如果组件是自动生成的id那种那么该项是null。 参阅#stateful了解记忆与复原的机制。

 

33、autoEl : Mixed 

某种标签的字符串或者Ext.DomHelper DomHelper配置对象,用于创建承载此组件的元素。

一般而言你无须对其设置。对于这些基础类而言,就会使用div作为其默认的元素。 Ext类写得越复杂,组件的onRender方法产生的DOM结构就随之更为复杂。

该项是为创建形形色色的DOM元素而准备的,开发者可根据程序的特定要求去制定,如:

 

34、disabledClass : String 

当组件被禁用时作用的CSS样式类(默认为”x-item-disabled”)。

 

35、allowDomMove : Boolean 

当渲染进行时能否移动Dom节点上的组件(默认为true)。

 

36、autoShow : Boolean 

True表示为在渲染的时候先检测一下有否关于隐藏的样式类(如:’x-hidden’或’x-hide-display’),有就移除隐藏的样式类(缺省为false)。 

 

37、hideMode : String 

这个组件是怎么隐藏的。可支持的值有”visibility” (css中的visibility),”offsets”(负偏移位置)和”display”(css中的display)-默认为“display”。 

容器可能是{@link Ext.layout.CardLayout card layout}或Ext.TabPanel TabPanel中的一员,会有隐藏/显未的情形,这种情形下最好将其hideMode模式设为”offsets”。这保证了计算布局时,组件仍有正确的高度和宽度,组件管理器才能顺利地测量。

 

38、hideParent : Boolean 

True表示为当隐藏/显示组件时对组件的容器亦一同隐藏/显示,false就只会隐藏/显示组件本身(默认为false)。例如,可设置一个hide:true的隐藏按钮在window,如果按下就通知其父容器一起隐藏,这样做起来比较快捷省事。 

 

39、listeners : Object 

 

公共事件事件  

1、clientvalidation( Ext.form.FormPanel this, Boolean valid ) 

2、

如果配置项monitorValid为true,那么为通知验证的状态(valid state)该事件将不断地触发。

侦听器会传入以下的参数:

this : Ext.form.FormPanel 

valid : Boolean 

如果客户端验证都通过的话传入一个true 

  

3、bodyresize( Ext.Panel p, Number width, Number height ) 

当面板的大小变化后触发。 

侦听器会传入以下的参数:

p : Ext.Panel 调节大小的面板。

width : Number 面板新宽度。

height : Number 面板新高度。

 

4、titlechange( Ext.Panel p, String t ) 

面板的标题有改动后触发。 

侦听器会传入以下的参数:

p : Ext.Panel 标题被改动的那个面板。

t : String 新标题。

 

5、iconchange( Ext.Panel p, String n, String o ) 

当面板的图标类设置了或改变了触发。 

侦听器会传入以下的参数:

p : Ext.Panel 图标类被改动的那个面板。

n : String 新图标类。

o : String 旧图标类

 

6、collapse( Ext.Panel p ) 

当面板被闭合后触发。 

侦听器会传入以下的参数:

p : Ext.Panel 闭合的那个面板

 

7、expand( Ext.Panel p ) 

当面板被展开后触发。

侦听器会传入以下的参数:

p : Ext.Panel 展开的面板。

 

8、beforecollapse( Ext.Panel p, Boolean animate ) 

当面板被闭合之前触发。若句柄返回false则取消闭合的动作。

侦听器会传入以下的参数:

p : Ext.Panel 正被闭合的面板。

animate : Boolean True表示闭合时带有动画效果。

 

9、beforeexpand( Ext.Panel p, Boolean animate ) 

当面板被展开之前触发。若句柄返回false则取消展开的动作。

侦听器会传入以下的参数:

p : Ext.Panel 正被展开的面板

animate : Boolean True表示闭合时带有动画效果。

 

10、beforeclose( Ext.Panel p ) 

当面板被关闭之前触发。 注意面板不直接支持“关闭”,不过在面板的子类(如Ext.Window)可支持即可调用该事件。 若句柄返回false则取消关闭的动作。

侦听器会传入以下的参数:

p : Ext.Panel 正被关闭的面板。

 

11、close( Ext.Panel p ) 

当面板被关闭后触发。 注意面板不直接支持“关闭”,不过在面板的子类(如Ext.Window)可支持即可调用该事件。 

侦听器会传入以下的参数:

p : Ext.Panel 已关闭的面板。

 

12、activate( Ext.Panel p ) 

当面板视觉上取消活动后触发。 注意面板不直接支持“取消活动”,不过在面板的子类(如Ext.Window)可支持即可调用该事件。 另外在TabPanel控制下子组件也会触发activate和deactivate事件。 

侦听器会传入以下的参数:

p : Ext.Panel 激活的面板。

 

13、deactivate( Ext.Panel p ) 

当面板视觉上“反激活”过后触发。 注意面板不直接支持“反激活”,但面板某些子类就支持(如Ext.Window)。 TabPanel控制其子面板的激活与反激活事件。

侦听器会传入以下的参数:

p : Ext.Panel 已反激活的面板。

Apache与Tomcat的三种连接方式介绍

首先我们先介绍一下为什么要让Apache与Tomcat之间进行连接。事实上Tomcat本身已经提供了HTTP服务,该服务默认的端口是8080,装好tomcat后通过8080端口可以直接使用Tomcat所运行的应用程序,你也可以将该端口改为80。

既然Tomcat本身已经可以提供这样的服务,我们为什么还要引入Apache或者其他的一些专门的HTTP服务器呢?原因有下面几个:

1. 提升对静态文件的处理性能

2. 利用Web服务器来做负载均衡以及容错

3. 无缝的升级应用程序

这三点对一个web网站来说是非常之重要的,我们希望我们的网站不仅是速度快,而且要稳定,不能因为某个Tomcat宕机或者是升级程序导致用户访问不了,而能完成这几个功能的、最好的HTTP服务器也就只有apache的http server了,它跟tomcat的结合是最紧密和可靠的。

接下来我们介绍三种方法将apache和tomcat整合在一起。

一. JK

这是最常见的方式,你可以在网上找到很多关于配置JK的网页,当然最全的还是其官方所提供的文档。JK本身有两个版本分别是1和2,目前1最新的版本是1.2.19,而版本2早已经废弃了,以后不再有新版本的推出了,所以建议你采用版本1。

JK是通过AJP协议与Tomcat服务器进行通讯的,Tomcat默认的AJP Connector的端口是8009。JK本身提供了一个监控以及管理的页面jkstatus,通过jkstatus可以监控JK目前的工作状态以及对到tomcat的连接进行设置,如下图所示

在这个图中我们可以看到当前JK配了两个连接分别到8109和8209端口上,目前s2这个连接是停止状态,而s1这个连接自上次重启后已经处理了47万多个请求,流量达到6.2个G,最大的并发数有13等等。我们也可以利用jkstatus的管理功能来切换JK到不同的Tomcat上,例如将s2启用,并停用s1,这个在更新应用程序的时候非常有用,而且整个切换过程对用户来说是透明的,也就达到了无缝升级的目的。关于JK的配置文章网上已经非常多了,这里我们不再详细的介绍整个配置过程,但我要讲一下配置的思路,只要明白了配置的思路,JK就是一个非常灵活的组件。

JK的配置最关键的有三个文件,分别是

httpd.conf 

Apache服务器的配置文件,用来加载JK模块以及指定JK配置文件信息

workers.properties

到Tomcat服务器的连接定义文件

uriworkermap.properties 

URI映射文件,用来指定哪些URL由Tomcat处理,你也可以直接在httpd.conf中配置这些URI,但是独立这些配置的好处是JK模块会定期更新该文件的内容,使得我们修改配置的时候无需重新启动Apache服务器。

其中第二、三个配置文件名都可以自定义。下面是一个典型的 httpd.conf 对JK的配置

# (httpd.conf)

# 加载mod_jk模块

LoadModule jk_module modules/mod_jk.so

#

# Configure mod_jk

#

JkWorkersFile conf/workers.properties

JkMountFile conf/uriworkermap.properties

JkLogFile logs/mod_jk.log

JkLogLevel warn

接下来我们在Apache的conf目录下新建两个文件分别是 workers.properties、uriworkermap.properties。这两个文件的内容大概如下

#

# workers.properties

#

# list the workers by name

worker.list=DLOG4J, status

# localhost server 1

# ————————

worker.s1.port=8109

worker.s1.host=localhost

worker.s1.type=ajp13

# localhost server 2

# ————————

worker.s2.port=8209

worker.s2.host=localhost

worker.s2.type=ajp13

worker.s2.stopped=1

worker.DLOG4J.type=lb

worker.retries=3

worker.DLOG4J.balanced_workers=s1, s2

worker.DLOG4J.sticky_session=1

worker.status.type=status

以上的workers.properties配置就是我们前面那个屏幕抓图的页面所用的配置。首先我们配置了两个类型为ajp13的worker分别是s1和s2,它们指向同一台服务器上运行在两个不同端口8109和8209的Tomcat上。接下来我们配置了一个类型为lb(也就是负载均衡的意思)的worker,它的名字是DLOG4J,这是一个逻辑的worker,它用来管理前面配置的两个物理连接s1和s2。最后还配置了一个类型为status的worker,这是用来监控JK本身的模块。有了这三个worker还不够,我们还需要告诉JK,哪些worker是可用的,所以就有worker.list = DLOG4J, status 这行配置。

接下来便是URI的映射配置了,我们需要指定哪些链接是由Tomcat处理的,哪些是由Apache直接处理的,看看下面这个文件你就能明白其中配置的意义

/*=DLOG4J

/jkstatus=status

!/*.gif=DLOG4J

!/*.jpg=DLOG4J

!/*.png=DLOG4J

!/*.css=DLOG4J

!/*.js=DLOG4J

!/*.htm=DLOG4J

!/*.html=DLOG4J

相信你已经明白了一大半了:所有的请求都由DLOG4J这个worker进行处理,但是有几个例外,/jkstatus请求由status这个worker处理。另外这个配置中每一行数据前面的感叹号是什么意思呢?感叹号表示接下来的URI不要由JK进行处理,也就是Apache直接处理所有的图片、css文件、js文件以及静态html文本文件。

通过对workers.properties和uriworkermap.properties的配置,可以有各种各样的组合来满足我们前面提出对一个web网站的要求。您不妨动手试试!

二. http_proxy

这是利用Apache自带的mod_proxy模块使用代理技术来连接Tomcat。在配置之前请确保是否使用的是2.2.x版本的Apache服务器。因为2.2.x版本对这个模块进行了重写,大大的增强了其功能和稳定性。

http_proxy模式是基于HTTP协议的代理,因此它要求Tomcat必须提供HTTP服务,也就是说必须启用Tomcat的HTTP Connector。一个最简单的配置如下

ProxyPass /images !

ProxyPass /css !

ProxyPass /js !

ProxyPass / http://localhost:8080/

在这个配置中,我们把所有 http://localhost 的请求代理到 http://localhost:8080/ ,这也就是Tomcat的访问地址,除了images、css、js几个目录除外。我们同样可以利用mod_proxy来做负载均衡,再看看下面这个配置

ProxyPass /images !

ProxyPass /css !

ProxyPass /js !

ProxyPass / balancer://example/

<Proxy balancer://example/>

BalancerMember http://server1:8080/

BalancerMember http://server2:8080/

BalancerMember http://server3:8080/

</Proxy>

配置比JK简单多了,而且它也可以通过一个页面来监控集群运行的状态,并做一些简单的维护设置。

三. ajp_proxy

ajp_proxy连接方式其实跟http_proxy方式一样,都是由mod_proxy所提供的功能。配置也是一样,只需要把http:// 换成 ajp:// ,同时连接的是Tomcat的AJP Connector所在的端口。上面例子的配置可以改为

ProxyPass /images !

ProxyPass /css !

ProxyPass /js !

ProxyPass / balancer://example/

<Proxy balancer://example/>

BalancerMember ajp://server1:8080/

BalancerMember ajp://server2:8080/

BalancerMember ajp://server3:8080/

</Proxy>

采用proxy的连接方式,需要在Apache上加载所需的模块,mod_proxy 相关的模块有

mod_proxy.so、mod_proxy_connect.so、mod_proxy_http.so、mod_proxy_ftp.so、mod_proxy_ajp.so, 其中mod_proxy_ajp.so只在Apache 2.2.x中才有。如果是采用 http_proxy 方式则需要加载 mod_proxy.so 和 mod_proxy_http.so;如果是 ajp_proxy 则需要加载 mod_proxy.so和mod_proxy_ajp.so这两个模块。

四. 三者比较

相对于JK的连接方式,后两种在配置上是比较简单的,灵活性方面也一点都不逊色。但就稳定性而言就不像JK这样久经考验,毕竟Apache 2.2.3推出的时间并不长,采用这种连接方式的网站还不多,因此,如果是应用于关键的互联网网站,还是建议采用JK的连接方式。

相关网址

Apache http://httpd.apache.org

Tomcat http://tomcat.apache.org

JK文档 http://tomcat.apache.org/connectors-doc/

ApacheHTTPServer与Tomcat的连接方式介绍

整合 Apache Http Server 和 Tomcat 可以提升对静态文件的处理性能、利用 Web 服务器来做负载均衡以及容错、无缝的升级应用程序。本文介绍了三种整合 Apache 和 Tomcat 的方式。

首先我们先介绍一下为什么要让 Apache 与 Tomcat 之间进行连接。事实上 Tomcat 本身已经提供了 HTTP 服务,该服务默认的端口是 8080,装好 tomcat 后通过 8080 端口可以直接使用 Tomcat 所运行的应用程序,你也可以将该端口改为 80。

既然 Tomcat 本身已经可以提供这样的服务,我们为什么还要引入 Apache 或者其他的一些专门的 HTTP 服务器呢?原因有下面几个:

1. 提升对静态文件的处理性能

2. 利用 Web 服务器来做负载均衡以及容错

3. 无缝的升级应用程序

这三点对一个 web 网站来说是非常之重要的,我们希望我们的网站不仅是速度快,而且要稳定,不能因为某个 Tomcat 宕机或者是升级程序导致用户访问不了,而能完成这几个功能的、最好的 HTTP 服务器也就只有 apache 的 http server 了,它跟 tomcat 的结合是最紧密和可靠的。

接下来我们介绍三种方法将 apache 和 tomcat 整合在一起。

JK

这是最常见的方式,你可以在网上找到很多关于配置JK的网页,当然最全的还是其官方所提供的文档。JK 本身有两个版本分别是 1 和 2,目前 1 最新的版本是 1.2.19,而版本 2 早已经废弃了,以后不再有新版本的推出了,所以建议你采用版本 1。

JK 是通过 AJP 协议与 Tomcat 服务器进行通讯的,Tomcat 默认的 AJP Connector 的端口是 8009。JK 本身提供了一个监控以及管理的页面 jkstatus,通过 jkstatus 可以监控 JK 目前的工作状态以及对到 tomcat 的连接进行设置,如下图所示:

在这个图中我们可以看到当前JK配了两个连接分别到 8109 和 8209 端口上,目前 s2 这个连接是停止状态,而 s1 这个连接自上次重启后已经处理了 47 万多个请求,流量达到 6.2 个 G,最大的并发数有 13 等等。我们也可以利用 jkstatus 的管理功能来切换 JK 到不同的 Tomcat 上,例如将 s2 启用,并停用 s1,这个在更新应用程序的时候非常有用,而且整个切换过程对用户来说是透明的,也就达到了无缝升级的目的。关于 JK 的配置文章网上已经非常多了,这里我们不再详细的介绍整个配置过程,但我要讲一下配置的思路,只要明白了配置的思路,JK 就是一个非常灵活的组件。

JK 的配置最关键的有三个文件,分别是

httpd.conf

Apache 服务器的配置文件,用来加载 JK 模块以及指定 JK 配置文件信息

workers.properties

到 Tomcat 服务器的连接定义文件

uriworkermap.properties

URI 映射文件,用来指定哪些 URL 由 Tomcat 处理,你也可以直接在 httpd.conf 中配置这些 URI,但是独立这些配置的好处是 JK 模块会定期更新该文件的内容,使得我们修改配置的时候无需重新启动 Apache 服务器。

其中第二、三个配置文件名都可以自定义。下面是一个典型的 httpd.conf 对 JK 的配置

# (httpd.conf)

# 加载 mod_jk 模块

LoadModule jk_module modules/mod_jk.so

#

# Configure mod_jk

#

JkWorkersFile conf/workers.properties

JkMountFile conf/uriworkermap.properties

JkLogFile logs/mod_jk.log

JkLogLevel warn

接下来我们在 Apache 的 conf 目录下新建两个文件分别是 workers.properties、uriworkermap.properties。这两个文件的内容大概如下

#

# workers.properties

#

# list the workers by name

worker.list=DLOG4J, status

# localhost server 1

# ————————

worker.s1.port=8109

worker.s1.host=localhost

worker.s1.type=ajp13

# localhost server 2

# ————————

worker.s2.port=8209

worker.s2.host=localhost

worker.s2.type=ajp13

worker.s2.stopped=1

worker.DLOG4J.type=lb

worker.retries=3

worker.DLOG4J.balanced_workers=s1, s2

worker.DLOG4J.sticky_session=1

worker.status.type=status

以上的 workers.properties 配置就是我们前面那个屏幕抓图的页面所用的配置。首先我们配置了两个类型为 ajp13 的 worker 分别是 s1 和 s2,它们指向同一台服务器上运行在两个不同端口 8109 和 8209 的 Tomcat 上。接下来我们配置了一个类型为 lb(也就是负载均衡的意思)的 worker,它的名字是 DLOG4J,这是一个逻辑的 worker,它用来管理前面配置的两个物理连接 s1 和 s2。最后还配置了一个类型为 status 的 worker,这是用来监控 JK 本身的模块。有了这三个 worker 还不够,我们还需要告诉 JK,哪些 worker 是可用的,所以就有 worker.list = DLOG4J, status 这行配置。

接下来便是 URI 的映射配置了,我们需要指定哪些链接是由 Tomcat 处理的,哪些是由 Apache 直接处理的,看看下面这个文件你就能明白其中配置的意义

/*=DLOG4J

/jkstatus=status

!/*.gif=DLOG4J

!/*.jpg=DLOG4J

!/*.png=DLOG4J

!/*.css=DLOG4J

!/*.js=DLOG4J

!/*.htm=DLOG4J

!/*.html=DLOG4J

相信你已经明白了一大半了:所有的请求都由 DLOG4J 这个 worker 进行处理,但是有几个例外,/jkstatus 请求由 status 这个 worker 处理。另外这个配置中每一行数据前面的感叹号是什么意思呢?感叹号表示接下来的 URI 不要由 JK 进行处理,也就是 Apache 直接处理所有的图片、css 文件、js 文件以及静态 html 文本文件。

通过对 workers.properties 和 uriworkermap.properties 的配置,可以有各种各样的组合来满足我们前面提出对一个 web 网站的要求。您不妨动手试试!

http_proxy

这是利用 Apache 自带的 mod_proxy 模块使用代理技术来连接 Tomcat。在配置之前请确保是否使用的是 2.2.x 版本的 Apache 服务器。因为 2.2.x 版本对这个模块进行了重写,大大的增强了其功能和稳定性。

http_proxy 模式是基于 HTTP 协议的代理,因此它要求 Tomcat 必须提供 HTTP 服务,也就是说必须启用 Tomcat 的 HTTP Connector。一个最简单的配置如下

ProxyPass /images !

ProxyPass /css !

ProxyPass /js !

ProxyPass / http://localhost:8080/

在这个配置中,我们把所有 http://localhost 的请求代理到 http://localhost:8080/ ,这也就是 Tomcat 的访问地址,除了 images、css、js 几个目录除外。我们同样可以利用 mod_proxy 来做负载均衡,再看看下面这个配置

ProxyPass /images !

ProxyPass /css !

ProxyPass /js !

ProxyPass / balancer://example/

<Proxy balancer://example/>

BalancerMember http://server1:8080/

BalancerMember http://server2:8080/

BalancerMember http://server3:8080/

</Proxy>

配置比 JK 简单多了,而且它也可以通过一个页面来监控集群运行的状态,并做一些简单的维护设置。

ajp_proxy

ajp_proxy 连接方式其实跟 http_proxy 方式一样,都是由 mod_proxy 所提供的功能。配置也是一样,只需要把 http:// 换成 ajp:// ,同时连接的是 Tomcat 的 AJP Connector 所在的端口。上面例子的配置可以改为:

ProxyPass /images !

ProxyPass /css !

ProxyPass /js !

ProxyPass / balancer://example/

<Proxy balancer://example/>

BalancerMember ajp://server1:8080/

BalancerMember ajp://server2:8080/

BalancerMember ajp://server3:8080/

</Proxy>

采用 proxy 的连接方式,需要在 Apache 上加载所需的模块,mod_proxy 相关的模块有 mod_proxy.so、mod_proxy_connect.so、mod_proxy_http.so、mod_proxy_ftp.so、mod_proxy_ajp.so, 其中 mod_proxy_ajp.so 只在 Apache 2.2.x 中才有。如果是采用 http_proxy 方式则需要加载 mod_proxy.so 和 mod_proxy_http.so;如果是 ajp_proxy 则需要加载 mod_proxy.so 和 mod_proxy_ajp.so这两个模块。

回页首

三者比较

相对于 JK 的连接方式,后两种在配置上是比较简单的,灵活性方面也一点都不逊色。但就稳定性而言就不像 JK 这样久经考验,毕竟 Apache 2.2.3 推出的时间并不长,采用这种连接方式的网站还不多,因此,如果是应用于关键的互联网网站,还是建议采用 JK 的连接方式。

Extjs开发使用

 

extjs基础

extjs基础

extjs是什么?

extjs能做什么?

术语

开发环境

界面模板

hello world

Element

UI控件

windows

panel

tabpanel

form

Grid

tree

布局

column layout 列布局

fit Layout

border Layout

accordion Layout

form Layout

table Layout

组件扩展

继承

学习资料

extjs是什么?

ExtJS可以用来开发RIA也即富客户端的AJAX应用,是一个用javascript写 的,主要用于创建前端用户界面,是一个与后台技术无关的前端ajax框架。因此,可以把ExtJS用在.Net、Java、Php等各种开发语言开发的应用中。ExtJs最开始基于YUI技术,由开发人员JackSlocum开发,通过参考JavaSwing等机制来组织可视化组件。该框架完全基于纯Html/CSS+JS技术,提供丰富的跨浏览器UI组件,灵活采用JSON/XML数据源开发。

extjs能做什么?

demo office

术语

一、组件:

1、组件:

所谓组件,就是指可以利用的应用程序组成部件 。EXT最大特点,就是拥有一个庞大、功能齐全、结构及层次分明的组件体系,并在组件的基础上进一步封装出各种实用的控件。我们在开发的时候,只需要直接 使用这些组件及控件 ,就可以创建出丰富多彩的应用程序界面。比如说窗口、树、表格、工具栏、菜等。

2、组件xtype

在Ext中,每一个组件都有一个类定义,比如按钮组件的类是Ext.Button类,空口控件的类是Ext.Window,除了可以通过类名来标识某一个组件以外,Ext还提出了一个xtype的概念,我们可以理解为组件类名的缩写,比如说Ext.tree.TreePanel类对应的类缩写 名称为treepanel。xtypes最大的用途是怎么用于优化组件的创建和渲染过程。 通过指定一个xtype的配置对象的写法,可隐式声明的方式创建组件,使得当不需要立即渲染的情况就只是一个对象,省去不必要的实例化步骤。这时不仅渲染的动作是延时的,而且创建实际对象的这一步也是延时的,从而节省了内存和资源。

3、组件的生存周期

基于组件的每个类,一个周期内各个重要阶段

初始化Initialization

1、配置项对象生效了

The config object is applied.

组件对象的构造器会把全部的配置项传入到其子类中去,并且进行下列所有的步骤。

2、组件的底层事件创建了

The base Component events are created

这些事件由组件对象负责触发。事件有enable, disable, beforeshow, show, beforehide, hide, beforerender, render, beforedestroy, destroy (参阅Component API文档完整的内容)。

3、组件在组件管理器里登记了

The component is registered in ComponentMgr

initComponent这方法总是使用在子类中,就其本身而论,该方法是一个模板方法(template method),用于每个子类去现实任何所需的构造器逻辑(any needed constructor logic)。首先会创建类,然后组件对象各层次里面的每个类都应该调用superclass.initComponent。通过该方法,就可方便地实现(implement),或重写(Override)任意一层构造器的逻辑。

4、状态感知进行初始化(如果有的话)

State is initialized (if applicable)

如果组件是状态感知的,其状态会进行刷新。

5、加载好插件(如果有的话)

Plugins are loaded (if applicable)

如果该组件有指定任何插件,这时便会初始化。

6、渲染好插件(如果必须的话)

The component is rendered (if applicable)

如果指定了组件的renderTo 或 applyTo配置属性,那么渲染工作就会立即开始,否则意味着延时渲染,即等待到显式控制显示,或是其容器告知其显示的命令。

   

渲染过程 Rendering

1、触发beforerender事件 The beforerender event is fired

这是个可取消的事件,指定的句柄(handler)可阻止组件进行渲染

2、设置好容器 The container is set

如果没有指定一个容器,那么将使用位于DOM元素中组件的父节点作为容器。

3、调用onRender方法 The onRender method is called

这是子类渲染最重要的一个步骤,由于该方法是一个模板方法(template method),用于每个子类去现实任何所需的渲染逻辑(any needed render logic)。首先会创建类,然后组件对象各层次里面的每个类都应调用superclass.onRender。通过该方法,就可方便地实现(implement),或重写(Override)任意一层渲染的逻辑。

4、组件是“隐藏”状态的 The Component is “unhidden”

默认下,许多组件是由CSS样式类如”x-hidden”设置隐藏的。如果 autoShow所配置的值为true,这时就不会有这个”hide”样式类作用在该组件上

5、自定义的类、样式生效了 Custom class and/or style applied

一切组件的子类都支持cls和style 两种特殊的配置属性,分别用于指定用户自定义的CSS样式类和CSS规则。 推荐指定cls的方法来制定组件及其各部分的可视化设置。由于该样式类会套用在组件markup最外的一层元素,所以标准CSS规则会继承到组件下任何子元素的身上。

6、触发render事件 The render event is fired

这是组件通知成功渲染的一个步骤。这时,你可肯定地认为组件的DOM元素是可用的了。如果尝试在渲染之前访问组件,会抛出一个不可用的异常。

7、调用了afterRender方法 The afterRender method is called

这是另外一个实现或重写特定所需的“后渲染”逻辑的模板方法。每个子类应调用superclass.afterRender.

8、组件被隐藏或禁用(如果有的话) The Component is hidden and/or disabled (if applicable)

配置项hidden和disabled到这步生效

9、所有状态感知的事件初始化(如果有的话) Any state-specific events are initialized (if applicable)

状态感知的组件可由事件声明特殊加载和保存状态。如支持,加入此类的事件。

销毁过程 Destruction

1、触发beforedesroy事件 The beforedestroy event is fired

这是个可取消的事件,指定的句柄(handler)可阻止组件被销毁。

2、调用了beforeDestroy方法 The beforeDestroy method is called

这是另外一个实现或重写预定销毁逻辑的模板方法。每个子类应调用superclass.beforeDestroy。

3、元素及其侦听器被移除 Element and its listeners are removed

若组件是渲染好的,所属的元素的事件侦听器和DOM树中的元素都会被移除。

4、调用了onDestroy方法 The onDestroy method is called

这是另外一个实现或重写特定所需的“后销毁”逻辑的模板方法。每个子类应调用superclass.onDestroy。注意 容器类(Container class,和一切容器的子类)提供了一个默认的onDestroy实现,自动遍历其items集合里的每一项,分别地执行子组件身上的destroy方法。

5、在组件管理器中撤销组件对象的登记 Component is unregistered from ComponentMgr

使得不能再从Ext.getCmp获取组件对象

6、触发destroy事件 The destroy event is fired

这是组件成功销毁的一个简单通知。此时组件已经DOM中已是不存在的了

7、组件上的事件侦听器被移除 Event listeners on the Component are removed

组件本身可允许从所属的元素得到事件侦听器。如有的话,连同删除。

二、类

数据支持类(data)

拖X支持类(dd)

布局支持类(layout)

本地状态存储支持类(state)

实用工具类(util)

三、方法

作为类的功能体现,能够产生改变对象本身产生变化的直接因素

四、事件

同类定义的、并且可以在类对象自身状态发生改变的触发。

五、配置选项

用以初始化一个EXTJS类对象的手段

六、属性

能够在程序运行期间被访问,用以了解当前类对象的状态

七、命名空间

能够将编写好的EXTJS类进行有效组织的手段

开发环境

aptana:

firebug:

界面模板

basepage

hello world

Ext.onReady(function(){

     alert(‘Hello world’);

})

Element

大多数的JavaScript操作都需要先获取页面上的某个元素的引用,好让你来做些实质性的事情。传统的JavaScript做法,是通过ID获取Dom节点的:

   var myDiv = document.getElementById(‘myDiv’);

这样单单返回一个对象(DOM节点),用起来并不是太实用和方便。为了要用那节点干点事情,你还将要手工编写不少的代码;另外,对于不同类型浏览器之间的差异,要处理起来可真头大了。

Element的API是整个Ext库的基础,无论是访问元素(elements)还是完成一些其他动作,都要涉及它。

Ext.onReady(function() {

var myDiv = Ext.get(‘mydiv’);

});

Element包含了常见的DOM方法和属性,提供一个快捷的、统一的、跨浏览器的接口(若使用Element.dom的话,就可以直接访问底层DOM的节点。);

Element.get()方法提供内置缓存(Cache),多次访问同一对象效率上有极大优势;

内置常用的DOM节点的动作,并且是跨浏览器的定位的位置、大小、动画、拖放等等(添加/移除 CSS 类, 添加/移除事件处理程序, 定位, 改变大小, 动画, 拖放)。

myDiv.highlight();      //黄色高亮显示然后渐退

myDiv.addClass(‘red’);  // 添加自定义CSS类 (在ExtStart.css定义)

myDiv.center();         //在视图中将元素居中

myDiv.setOpacity(.25);  // 使元素半透明

获取多个DOM节点

想获取多个DOM的节点,难以依靠ID的方式来获取。有可能因为没设置ID,或者你不知道ID,又或者直接用ID方式引用有太多元素了。这种情况下,你就会不用ID来作为获取元素的依据,可能会用属性(attribute)或CSS Classname代替。基于以上的原因,Ext引入了一个异常强大的Dom Selector库,叫做DomQuery。

DomQuery可作为单独的库使用,但常用于Ext,你可以在上下文环境中(Context)获取多个元素,然后通过Element接口调用。令人欣喜的是,Element对象本身便有Element.select的方法来实现查询,即内部调用DomQuery选取元素。

// 每段高亮显示

Ext.select(‘p’).highlight();

DomQuery的选取参数可以是一段较长的数组,其中包括W3C CSS3 Dom选取器、基本XPatch、HTML属性 Ext.DomQuery

响应事件

Ext.onReady(function() {

var paragraphClicked = function(e) {

Ext.get(e.target).highlight();

}

Ext.select(‘p’).on(‘click’, paragraphClicked);

});

e.target是DOM节点,所以我们首先将其转换成为EXT的Elemnet元素,然后执行欲完成的事件,这个例子中,我们看见段落是高亮显示的。

UI控件

windowsWindow 是一种可浮动的、可最小/最大化的、可复原的、可拖动的..等此类的特殊面板。

alert:

      Ext.Msg.alert( title , msg , function(btn){} )

title,msg为必选参数,function为可选参数,在关闭弹出窗口后触发。

    //widow.alert(‘hello spoto’)!//默认警告框

    Ext.Msg.alert(‘Hello’,’Hello SPOTO’);//ext 警告框

btn:两种值ok,cancel

confirm

参数同confirm

Ext.Msg.confirm(‘title’, ‘msg’, function(btn){

    if (btn == ‘ok’){

        //处理或者关闭

    }

});

btn:三种值(yes,no,cancel)

prompt

Ext.Msg.prompt(‘Name’, ‘Please enter your name:’, function(btn, text){

    if (btn == ‘ok’){

        //处理text或者关闭

    }

});

show

功能很强大,采用config配置形式,比前面的方法使用更方便。

参数很多,在此列举最常用的配置参数:

animEl:对话框弹出和关闭时的动画效果,比如设置为“id1”,则从id1处弹出并产生动画,收缩则相反

buttons:弹出框按钮的设置,主要有以下几种:Ext.Msg.OK, Ext.Msg.OKCANCEL,Ext.Msg.CANCEL, Ext.Msg.YESNO, Ext.Msg.YESNOCANCEL 你也可以自定义按钮上面的字:{“ok”,”我本来是ok的”}。 若设为false,则不显示任何按钮.

closable:如果为false,则不显示右上角的小叉叉,默认为true。

msg:”消息的内容”

title:”标题”

fn:关闭弹出框后执行的函数

icon:弹出框内容前面的图标,取值为Ext.MessageBox.INFO, Ext.MessageBox.ERROR, Ext.MessageBox.WARNING, Ext.MessageBox.QUESTION

width:弹出框的宽度,不带单位

prompt:设为true,则弹出框带有输入框

multiline:设为true,则弹出框带有多行输入框

progress:设为true,显示进度条,(但是是死的)

progressText:显示在进度条上的字

wait:设为true,动态显示progress

waitConfig:配置参数,以控制显示progress

Ext.MessageBox.show({

    title:”标题”,

    msg:”内容的消息”,

    buttons:{“ok”:”我不再显示OK了”},

    fn:function(e){alert(e);},

    animEl:”test1″,

     width:500,

    icon:Ext.MessageBox.INFO,

    closable:false,

    progress:true,

    wait:true,

    progressText:”进度条”

   // prompt:true

   // multiline:true

});

进度条的使用

Ext.MessageBox.hide()

Ext.MessageBox.updateProgress(value,”ProgressText”,”msg”)

value为0-1之间的数,表示进度条的进度

Ext.get(‘btn1’).on(‘click’,function(){

             Ext.MessageBox.show({

                 title:”df”,

                 msg:”dfd”,

                 progress:true,

                 width:300,

                 closable:true

             });

             var f=function(v){

               return function(){

                 if(v==12)

                 {

                   Ext.MessageBox.hide();

                   //alert(“加载完成!”);

                 }

                 else

                 {

                   var i=v/11;

                   Ext.MessageBox.updateProgress(i,Math.round(100*i)+”% completed”,i);

                 }

               }

             }

             for(var i=1;i<13;i++)

             {

               setTimeout(f(i),i*500);//从点击时就开始计时,所以500*i表示每500ms就执行一次

             }

        })   

固定时间控制进度加载

Ext.get(“btn1”).on(

          “click”,

          function(){

             Ext.MessageBox.show({

                 title:”时间进度条”,

                 msg:”5s后关闭进度框”,

                 progress:true,

                 width:300,

                 wait:true,

                 waitConfig:{interval:600},//0.6s进度条自动加载一定长度

                 closable:true

             });

             setTimeout(function(){Ext.MessageBox.hide()},5000);//5后执行关闭窗口函数

          }

Ext.Window

var win;

            win = new Ext.Window({

                applyTo:’hello-win’,

                layout:’fit’,

                width:500,

                height:300,

                closeAction:’hide’,

                //plain: true,

                html:’fsdafsdf’,

                buttons: [{

                    text:’Submit’,

                    disabled:true

                },{

                    text: ‘Close’,

                    handler: function(){

                        win.hide();

                    }

                }]

            });

win.show();

panel面板Panel是2.0最常用的容器,90%布局任务都离不开面板。布局里的排版元素便是面板,面板如同一张白纸,完全是空白的矩形,没有可视内容。虽然这样,面板也提供了一些预留区域, 方便加入程序所需的UI界面,包括顶部或底部的工具条、菜单栏、头部区域、底部区域和躯干区域。同时内建可展开和可收缩行为的按钮,和其它不同任务预设的按钮。

extjs:

     var panel=new Ext.Panel({

                title:”面板”,

width:500,

height:300

// tbar:[{text:’顶部工具栏’},],

// bbar:[{text:’底部工具栏’}]

}

);

panel.render(‘panel’);

html

<div id=”panel”></div>

配置参数:

autoLoad:有效的url字符串,把那个url中的body中的数据加载显示,但是可能没有样式和js控制,只是html数据

autoScroll:设为true则内容溢出的时候产生滚动条,默认为false

autoShow:设为true显示设为”x-hidden”的元素,很有必要,默认为false

bbar:底部条,显示在主体内,//代码:bbar:[{text:’底部工具栏bottomToolbar’}],

tbar:顶部条,显示在主体内,//代码:tbar:[{text:’顶部工具栏topToolbar’}],

buttons:按钮集合,自动添加到footer中(footer参数,显示在主体外)//代码:buttons:[{text:”按钮位于footer”}]

buttonAlign:footer中按钮的位置,枚举值为:”left”,”right”,”center”,默认为right

collapsible:设为true,显示右上角的收缩按钮,默认为false

draggable:true则可拖动,但需要你提供操作过程,默认为false

html:主体的内容

id:id值,通过id可以找到这个组件,建议一般加上这个id值

width:宽度

height:高度

title:标题

titleCollapse:设为true,则点击标题栏的任何地方都能收缩,默认为false.

applyTo:(id)呈现在哪个html元素里面

contentEl:(id)呈现在哪个html元素里面,把el内的内容呈现

renderTo:(id)呈现在哪个html元素里面

渲染:

applyTo是将组件加在了指定元素之后,而renderTo则是加在指定元素之内。

applyTo与renderTo区别

//applyTo将组件 渲染到某一个节点的父节点

var applyTo=new Ext.Panel({title:’面板_applyTo’,width:300,height:300,applyTo:’applyTo’});

//指定el参数,然后直接调用render方法来渲染组件

var el=new Ext.Panel({title:’面板_el’,width:300,height:300,el:’el’})

el.render();

//renderTo渲染到页面中的某一个节点

var renderTo=new Ext.Panel({title:’面板_renderTo’,width:300,height:300,renderTo:’renderTo’})

alert(renderTo.el.dom.innerHTML);

tabpanelvar tabs = new Ext.TabPanel({

        renderTo: document.body,

        width:450,

        height:300,

        activeTab: 0,//0 是指,默认显示(访问)的是哪一个子面板。0是第一次,如果不指定该属性,默认不显示子面板内容,只有当用户点击子面板后才显示。

        defaults:{autoHeight: true},//默认自适应高度

        items:[

            {contentEl:’script’, title: ‘Short Text’},

            {contentEl:’markup’, title: ‘Long Text’,disabled:true},

            {autoLoad: {url: ‘data/ajax.html’, params: ‘foo=bar&wtf=1’},

             title: ‘ajax’,

             listeners: {activate: function(){alert(‘f’)}}

            }

        ]

    });

items 属性,表示子面板组。内容可以用html 元素ID 。比如:

items:[

             {contentEl:’script’, title: ‘Short Text’},

             {contentEl:’markup’, title: ‘Long Text’}

         ]

这样这两个子面板的内容将是ID为sript 和markup 的元素内容。

也可以,以html属性直接表示子面板的内容:

    items:[

             {html:’script’, title: ‘Short Text’},

             {html:’markup’, title: ‘Long Text’}

         ]

autoLoad: {url: ‘data/ajax.html’, params: ‘foo=bar&wtf=1’}

指切换到这个页面,内容显示为动态加载的,比如这里用了一个ajax方式,url 发送目标,params是参数形式。

listeners: {activate: handleActivate}

当面板切换到这个页面将触发事件:handleActivate

    disabled:true

指这个页面不能点击

formExtjs对普通的html form进行了一些封装,使其具有基本的外观和一些简便的和服务器进行通信的方法。Extjs中的表单组件是Ext.form.BasicForm,不过最简单最常用的是Ext.form.FormPanel控件,它继承自Panel,具有一定的界面显示控制能力,它其中包含着一个BasicForm对象,用来执行向服务器提交,加载等动作。Extjs也对常用的html表单项进行了封装,提供了一些额外的功能,比如数据验证。实际使用的时候只要向 FormPanel中添加这些表单项即可。常见的表单项有,TextField,NumberField,Radio,CheckBox等。

    var top = new Ext.FormPanel({

        labelAlign: ‘top’,//label对齐方式

        frame:true,//圆角显示

        title: ‘Multi Column, Nested Layouts and Anchoring’,//标题

        bodyStyle:’padding:5px 5px 0′,//样式

        width: 600,

        items: [{//表单元素

            layout:’column’,

            items:[{

                columnWidth:.5,//50%

                layout: ‘form’,//布局方式

                items: [{

                    xtype:’textfield’,//文本框

                    fieldLabel: ‘First Name’,

                    name: ‘first’,

                    anchor:’95%’//宽度=容器宽度的50%”   (-10, -250′,”宽度=容器宽度-10,高度=容器宽度-250″)

                }, {

                    xtype:’textfield’,

                    fieldLabel: ‘Company’,

                    name: ‘company’,

                    anchor:’95%’

                }]

            },{

                columnWidth:.5,

                layout: ‘form’,

                items: [{

                    xtype:’textfield’,

                    fieldLabel: ‘Last Name’,

                    name: ‘last’,

                    anchor:’95%’

                },{

                    xtype:’textfield’,

                    fieldLabel: ‘Email’,

                    name: ’email’,

                    vtype:’email’,

                    anchor:’95%’

                }]

            }]

        },{

            xtype:’htmleditor’,//编辑器

            id:’bio’,

            fieldLabel:’Biography’,

            height:200,

            anchor:’98%’

        }],

        buttons: [{

            text: ‘Save’,

           handler : function() { 

                var formpanel1 =top; 

                if (formpanel1.form.isValid()) {

                    this.disabled = true; 

                    formpanel1.getForm().submit({ 

                          url : ‘save.action’,//提交给后台。后台相应save方法。此处成功调用了该方法 

                          method : ‘post’, 

                          waitTitle : ‘请稍等……’, 

                          waitMsg : ‘正在上传数据……’,

                          success : function() { 

                            Ext.Msg.alert(“成功”, “操作成功!”); 

                            this.disabled = false; 

                        }, 

                        failure : function() { 

                        Ext.Msg.alert(“出错啦”, “数据保存失败!”); 

                        this.disabled = false; 

                        } 

                        }); 

                }

          }

        },{

            text: ‘Cancel’

        }]

    });

    top.render(document.body);

GridGrid控件和其它可以显示 数据的控件,能够支持多种数据类型,如二 维数组、Json数据和XML数据,甚至包括我们 自定义的数据类型。Ext为我们提供了一个桥梁 Ext.data.Store,通过它我们可以把任何 格式的数据转化成grid可以使用的形式,这样就不需要为每种数据格式写一个grid的实现了。

Ext.onReady(function() {

// 定义一个ColumnModel,表头中有四列

var cm = new Ext.grid.ColumnModel([

{header: ‘ 编号 ‘ ,dataIndex: ‘ id ‘ },

{header: ‘ 性 别 ‘ ,dataIndex: ‘ sex ‘ },

{header: ‘ 名 称 ‘ ,dataIndex: ‘ name ‘ },

{header: ‘ 描 述 ‘ ,dataIndex: ‘ descn ‘ }

]);

cm.defaultSortable = true;

该ColumnModel定义了表格的四个列,其每列的名称和对应的数据键。请注意defaultSortable属性,即为每个列都安上一个可以排序的功能。如果只想某些列举有该功能,可以设置:

    header:’编号’,dataIndex:’id’,Sortable:true

Ext.data.Store

//二维数组:

// ArrayData

var data = [

[ ‘ 1 ‘ , ‘ male ‘ , ‘ name1 ‘ , ‘ descn1 ‘ ],

[ ‘ 2 ‘ , ‘ male ‘ , ‘ name1 ‘ , ‘ descn2 ‘ ],

[ ‘ 3 ‘ , ‘ male ‘ , ‘ name3 ‘ , ‘ descn3 ‘ ],

[ ‘ 4 ‘ , ‘ male ‘ , ‘ name4 ‘ , ‘ descn4 ‘ ],

[ ‘ 5 ‘ , ‘ male ‘ , ‘ name5 ‘ , ‘ descn5 ‘ ]

];

// ArrayReader

var ds = new Ext.data.Store({

proxy: new Ext.data.MemoryProxy (data),

reader: new Ext.data.ArrayReader ({}, [

{name: ‘ id ‘ },

{name: ‘ sex ‘ },

{name: ‘ name ‘ },

{name: ‘ descn ‘ }

])

});

ds.load();

ds要对应两个部分:proxy和reader。proxy告诉我们从哪里获得数据,reader告诉我们如何解析这个数据。

现在用的是Ext.data.MemoryProxy,它将内存中的数据data作为参数传递。Ext.data.ArrayReader专门用来解析数 组,并且告诉我们它会按照定义的规范进行解析,每行按顺序读取四个数据,第一个叫id,第二个叫sex,第三个叫name,第四个descn。这些是跟 cm定义中的dataIndex对应的。这样cm就知道哪列应该显示那条数据了。

记得要执行一次ds.load(),对数据进行初始化。

数据显示:

var grid = new Ext.grid.GridPanel({

title:’数据列表’,

height:200,

width:500,

ds: ds,

cm: cm

});

grid.render(document.body);

});

*表格中添加CheckBox*

var sm = new Ext.grid.CheckboxSelectionModel();

var cm = new Ext.grid.ColumnModel([

    new Ext.grid.RowNumberer(),//自动行号

    sm,//添加的地方

    {header:’编号’,dataIndex:’id’},

    {header:’性别’,dataIndex:’sex’},

    {header:’名称’,dataIndex:’name’},

    {header:’描述’,dataIndex:’descn’}

]);

var grid = new Ext.grid.GridPanel({

    el: ‘grid3’,

    ds: ds,

    cm: cm,

    sm: sm,//添加的地方

    title: ‘HelloWorld’

});

在Grid上触发事件

grid.addListener(‘cellclick’, cellclick);

function cellclick(grid, rowIndex, columnIndex, e) {

    var record = grid.getStore().getAt(rowIndex);   //Get the Record

    var fieldName = grid.getColumnModel().getDataIndex(columnIndex); //Get field name

    var data = record.get(fieldName);

    Ext.MessageBox.alert(‘show’,’当前选中的数据是’+data);

}

Grid中右击快捷菜单

grid.addListener(‘rowcontextmenu’, rightClickFn);//右键菜单代码关键部分

var rightClick = new Ext.menu.Menu({

    id:’rightClickCont’,

    items: [

        {

            id: ‘rMenu1’,

            handler: rMenu1Fn,//点击后触发的事件

            text: ‘右键菜单1’

        },

        {

            //id: ‘rMenu2’,

            //handler: rMenu2Fn,

            text: ‘右键菜单2’

        }

    ]

});

function rightClickFn(grid,rowindex,e){

    e.preventDefault();//阻止默认行为,如:阻止脚本运行或者阻止事件处理函数的执行

    rightClick.showAt(e.getXY());//显示位置

}

function rMenu1Fn(){

   Ext.MessageBox.alert(‘right’,’rightClick’);

}

   

将一列中的数据根据要求进行格式化

比如说性别字段根据其male或female改变显示的颜色,这种ColumnMode中设计:

var cm = new Ext.grid.ColumnModel([

    new Ext.grid.RowNumberer(),

    sm,

    {header:’编号’,dataIndex:’id’},

    {header:’性别’,dataIndex:’sex’,renderer:changeSex},

    {header:’名称’,dataIndex:’name’},

    {header:’描述’,dataIndex:’descn’}

]);

cm.defaultSortable = true;

function changeSex(value){

    if (value == ‘male’) {

        return “<span style=’color:red;font-weight:bold;’>红男</span>”;

    } else {

        return “<span style=’color:green;font-weight:bold;’>绿女</span>”;

    }

}

Json数据

var data = {

    ‘coders’: [

        { ‘id’: ‘1’, ‘sex’: ‘male’, ‘name’:’McLaughlin’, ‘descn’: ‘brett@newInstance.com’ },

        { ‘id’: ‘2’, ‘sex’: ‘male’,’name’:’Hunter’, ‘descn’: ‘jason@servlets.com’ },

        { ‘id’: ‘3’, ‘sex’: ‘female’,’name’:’Harold’, ‘descn’: ‘elharo@macfaq.com’ },

        { ‘id’: ‘4’, ‘sex’: ‘male’,’name’:’Harolds’, ‘descn’: ‘elhaross@macfaq.com’ }

    ],

    ‘musicians’: [

        { ‘id’: ‘1’, ‘name’: ‘Clapton’, ‘descn’: ‘guitar’ },

        { ‘id’: ‘2’, ‘name’: ‘Rachmaninoff’, ‘descn’: ‘piano’ }

    ]

}

//ds使用的MemoryProxy对象和JsonReader对象

var ds = new Ext.data.Store({

        proxy: new Ext.data.MemoryProxy(data),

        reader: new Ext.data.JsonReader({root: ‘coders’}, [

            {name: ‘id’},

            {name: ‘sex’},

            {name: ‘name’},

            {name: ‘descn’}

        ])

    });

ds.load();

var grid = new Ext.grid.GridPanel({

    el: ‘grid3’,

    ds: ds,

    cm: cm,

    sm: sm,

    title: ‘HelloWorld’,

    autoHeight: true//一定要写,否则显示的数据会少一行

});

grid.render();

从服务器获取数据和数据翻页控件

服务端返回数据(参数:start和limit):

    {totalProperty:100,root:[{‘id’:’0′,’name’:’name0′,’descn’:’descn0′},{‘id’:’1′,’name’:’name1′,’descn’:’descn1′},{‘id’:’2′,’name’:’name2′,’descn’:’descn2′},{‘id’:’3′,’name’:’name3′,’descn’:’descn3′},{‘id’:’4′,’name’:’name4′,’descn’:’descn4′},{‘id’:’5′,’name’:’name5′,’descn’:’descn5′},{‘id’:’6′,’name’:’name6′,’descn’:’descn6′},{‘id’:’7′,’name’:’name7′,’descn’:’descn7′},{‘id’:’8′,’name’:’name8′,’descn’:’descn8′},{‘id’:’9′,’name’:’name9′,’descn’:’descn9′}]}

我们使用分页控件来控制Grid的数据:

var sm = new Ext.grid.CheckboxSelectionModel();

   

    var cm = new Ext.grid.ColumnModel([

        new Ext.grid.RowNumberer(),

        sm,

        {header:’编号’,dataIndex:’id’},

        {header:’性别’,dataIndex:’sex’},

        {header:’名称’,dataIndex:’name’},

        {header:’描述’,dataIndex:’descn’}

    ]);

    cm.defaultSortable = true;

    var ds = new Ext.data.Store({

        proxy: new Ext.data.HttpProxy({url:’data.asp’}),

        reader: new Ext.data.JsonReader({

            totalProperty: ‘totalProperty’,

            root: ‘root’

        }, [

            {name: ‘id’},

            {name: ‘name’},

            {name: ‘descn’}

        ])

    });

    ds.load({params:{start:0,limit:10}});

   

    var grid = new Ext.grid.GridPanel({

        el: ‘grid3’,

        ds: ds,

        cm: cm,

        sm: sm,

        title: ‘ASP->JSON’,

        bbar: new Ext.PagingToolbar({

            pageSize: 10,

            store: ds,

            displayInfo: true,

            displayMsg: ‘显示第 {0} 条到 {1} 条记录,一共 {2} 条’,

            emptyMsg: “没有记录”

        }),

        tbar: new Ext.PagingToolbar({

            pageSize: 10,

            store: ds,

            displayInfo: true,

            displayMsg: ‘显示第 {0} 条到 {1} 条记录,一共 {2} 条’,

            emptyMsg: “没有记录”

        })

    });

    grid.render();

})

在Grid的上方添加按钮

var grid = new Ext.grid.GridPanel({

    el: ‘grid3’,

    ds: ds,

    cm: cm,

    sm: sm,

    title: ‘HelloWorld’,

    tbar: new Ext.Toolbar({

        items:[

                {

                    id:’buttonA’

                    ,text:”Button A”

                    ,handler: function(){ alert(“You clicked Button A”); }

                }

                ,

                new Ext.Toolbar.SplitButton({})

                ,{

                    id:’buttonB’

                    ,text:”Button B”

                    ,handler: function(){ alert(“You clicked Button B”); }

                }

                ,

                ‘-‘

                ,{

                    id:’buttonc’

                    ,text:”Button c”

                }

            ]

        })

});

tree// shorthand

    var Tree = Ext.tree;

    var tree = new Tree.TreePanel({

        autoScroll: true,

        animate: true,

        enableDD: true,

        containerScroll: true,

        width:300,

        //border: false,

        // auto create TreeLoader

        dataUrl: ‘data/json.php’,

        root: {

            nodeType: ‘async’,

            text: ‘Ext JS’,

            draggable: false,

            id: ‘src’

        }

    });

    // render the tree

    tree.render(document.body);

    tree.getRootNode().expand();

Ext.tree.TreeLoader:

   [{

        id: 1,

        text: ‘A leaf Node’,

        leaf: true

    },{

        id: 2,

        text: ‘A folder Node’,

        children: [{

            id: 3,

            text: ‘A child Node’,

            leaf: true

        }]

   }]

tree_php_mysql

布局

column layout 列布局在子元素中指定使用columnWidth或width来指定子元素所占的列宽度。 columnWidth表示使用百分比的形式指定列宽度。 width则是使用绝对象素的方式指定列宽度,在实际应用中可以混合使用两种方式。

new Ext.Panel({

   renderTo:document.body,

   width:600,

   height:300,

   layout:’column’,

   items:[{

       columnWidth:.5,

       title:’面板1′

   },{

       columnWidth:.5,

       title:’面板2′

   }]

})

fit LayoutFit布局,子元素将自动填满整个父容器(对元素设置宽度无效),如果容器组件中有多个子元素,则只会显示第一个子元素。

   

var win = new Ext.Window({

            title: “Hello World”,

            renderTo: document.body,

            width: 400,

            height: 250,

            x: 150,

            y: 50,

            layout: “fit”,

            items: [

                {xtype:”panel”, title:”O”},

                {xtype:”panel”, title:”K”}

            ]

        });

       

        win.show();

   

border LayoutBorder布局由类Ext.layout.BorderLayout定义,布局名称为border。该布局把容器分成东南西北中五个区域,分别由east,south, west,north, cente来表示,在往容器中添加子元素的时候,我们只需要指定这些子元素所在的位置,Border布局会自动把子元素放到布局指定的位置。 Viewport用于做整体布局 视见区Viewport是以document.body作容器的实用类,它会与浏览器视图自适应尺寸,是全屏幕应用的基础,如浏览器大小调节、布局重新计算的问题由该类自动完成。 注意视见区Viewport除了document.body元素外不能渲染在其它的容器上,所以一个页面只能有一个视见区。

new Ext.Viewport({

            layout:”border”,

            items:[

            {

                region:”north”,

                height:80,

                xtype: “label”,

                //style: “border: 1px solid red;padding:1px;”,

                frame: true,

                text: “cdred.net study club”

            },

            {

                region:”south”,

                height:20,

                xtype:’label’,

                text:’Status show zone..’

            },

            {

                region:”center”,

                title:”中央面板”

            },

            {

                region:”west”,

                width:200,

                title:”系统栏目”,

                collapsible: true

            },

            {

                region:”east”,

                width:150,

                collapsed: true,

                collapsible: true,

                title:”在线好友”

            }

               

                ]

       

});

accordion LayoutAccordion布局由类Ext.layout.Accordion定义,表示可折叠的布局,点击每一个子元素的头部名称或右边的按钮,则会展开该面板,并收缩其它已经展开的面板。

注意如果你是用 panel之类的 必须拥有 title:” 属性

               new Ext.Panel({

   renderTo:document.body,

title:’容器’,

width:500,

height:300,

layout:’accordion’,

layoutConfig:{

animate:true//启动动画效果

},

items:[

   {title:’子元素1′,html:’这是子元素1′},

   {title:’子元素2′,html:’这是子元素2′},

   {title:’子元素3′,html:’这是子元素3′}

]

   })   

form LayoutForm布局由类Ext.layout.FormLayout定义,名称为form,是一种专门用于管理表单中输入字段的布局,这种布局主要用于在程序中创建表单字段或表单元素等使用。

Ext.form.FormPanel这个类默认布局使用的是Form布局,因此我们直接使用FormPanel即可。

var panel = new Ext.Panel({

            layout:”form”,

            title: “form”,

            renderTo:document.body,

            width: 400,

            height:250,

            frame: true,

            hideLabel: true,

            collapsible: true,//控制收缩

            labelAlign:right,

            bodyStyle: “padding:20px;”,

            defaultType:”textfield”,

            items:[

                {fieldLabel:”Hello”},

                {fieldLabel:”World”}

            ]

        });

table LayoutTable布局由类Ext.layout.TableLayout定义,类以于html中的table,可以对行或列进行合并。

var panel = new Ext.Panel({

        title: “Hello World”,

        renderTo:document.body,

        layout: “table”,

        width: 500,

        height: 300,

        bodyStyle:’padding:20px;’,

        layoutConfig: {

            columns: 3

        },

        items: [

            {xtype:”panel”, title:”hello”, html:”hello context”, rowspan:2,height:95},

            {xtype:”panel”, title:”world”, html:”world context”, colspan:2},

            {xtype:”panel”, title:”fu”, html:”cheng context”},

            {xtype:”panel”, title:”zhou”, html:”du context”}

        ]

    });

组件扩展

有时候你打算生成一个带有若干配置项(config options)的组件(component),这些配置项你会想是让它可复的。就好像一种情况,有一部分的面板是已经固定好高、宽的,其中只有标题是不同的,我们可以把它做成预配置类(preconfigured class)。

使用构造器函数

构造器函数是完成该任务的方法之一,如下例:

// 构造器函数

var MyPanel = function(config) {

    Ext.apply(this, {

        // 在这里设定预配置的参数项

        width: 300,

        height: 300

    });

    MyPanel.superclass.constructor.apply(this, arguments);

};

// My Panel继承了Ext.Panel

Ext.extend(MyPanel, Ext.Panel, {});

var myfirstpanel = new MyPanel({

    title: ‘My First Panel’

});

var mysecondpanel = new MyPanel({

    title: ‘My Second Panel’

});

工厂模式

生成“预配置对象”的一种途径是使用工厂模式(Factong Design Pattern)。透过工厂函数返回一个全新的实例(该函数包含了预先配置好的参数项),工厂模式的方法不需要类的继承。 如果纯粹为了制定固定的配置项参数来讲工厂模式是一个不错的方法,其内部原理比继承、覆盖某个类来得简单。

function createMyPanel(config) {

    return new Ext.Panel(Ext.apply({//在这里设定预配置的参数项

        width: 300,

        height: 300

    }, config));

};

var myfirstpanel = createMyPanel({

    title: ‘My First Panel’

});

var mysecondpanel = createMyPanel({

    title: ‘My Second Panel’

});

   

扩展功能

使用OO的类的其中一个原因是你打算从另外一个类的基础上扩展新的功能,假设现在有一面板类,我们在此基础上增加一个新的方法并重写(override)父类的一个方法,过程如下:

// Constructor

var MyPanel = function(config) {

    //这里复用配置项

    Ext.apply(this,

        width: 300,

        height: 300

    });

    // 调用父类的构造函数,提取父类的功能

    MyPanel.superclass.constructor.apply(this, arguments);

    // 在这里你可以为当前对象新添加功能

    // 如事件:

    this.on(‘click’, function() {alert(“You Clicked ” + this.title);}, this);

};

// My Panel继承了Ext.Panel

Ext.extend(MyPanel, Ext.Panel, {

    // 在这里你可以为当前的类加入静态的变量,所有这个类生成的实例都是使用这里声明的变量

    // 如果你不确定请在构造器内设定。不要在这里放置由’new’或’xtype’操作而成的对象。在构造器内设定配置项对象会更安全。

    // 新添加的函数

    myNewFunction: function() {

    },

    // 重写原有函数

    onRender: function() {

        MyPanel.superclass.onRender.apply(this, arguments);

        this.myNewFunction();

    }

});

var myfirstpanel = new MyPanel({

    title: ‘My First Panel’

});

var mysecondpanel = new MyPanel({

    title: ‘My Second Panel’

});

   

另一种方法是用构造器的方式写出代码:

var MyPanel = function(config) {

    // 调用父类的构造函数,提取父类的功能

    MyPanel.superclass.constructor.call(this, Ext.apply({

        //这里复用配置项

        width: 300,

        height: 300

    }, config));

    // 位于构造器之后,在这里你可以为当前对象新添加功能(如处理如事件)

    this.on(‘click’, function() {alert(“你已点击” + this.title);}, this);

};

   

以上的方法是重写构造器的方式实现继承的,另外我们还可以重写initComponents方法写出相同的功能,但需要指出是initComponent方法是属于 Ext.Components的方法,只能在组件上使用,不是一个通用的方法。这里是一个示例:

var MyPanel = Ext.extend(Ext.Panel, {

    // 在这里你可以为当前的类加入静态的变量,所有这个类生成的实例都是使用这里声明的变量

    // 如果你不确定请在构造器内设定。不要在这里放置由’new’或’xtype’操作而成的对象。在构造器内设定配置项对象会更安全。

    initComponent: function() {

        //Reusable config options here

        Ext.apply(this,

            width: 300,

            height: 300

        });

       // 调用父类的构造函数,提取父类的功能

       MyPanel.superclass.initComponent.apply(this, arguments);

        // 位于构造器之后,在这里你可以为当前对象新添加功能(如处理如事件)

        this.on(

            ‘click’,

            function() {

                alert(“你已点击” + this.title);

            },

            this

        );

    },

    // 新添加的函数

    myNewFunction: function() {

    },

    // 重写原有函数

    onRender: function() {

        MyPanel.superclass.onRender.apply(this, arguments);

        this.myNewFunction();

    }

});

   

你首先可能会观察到的是这儿没有构造函数。Ext会为你创建构造函数。这个构造函数有点不同,叫initComponent。

这在高级教程和例子常见的使用方法。只要简单记住它做的事情与构造函数是差不多的。

推荐在调用父类的构造器或initComponent方法之后,为当前对象新添加事件。

MyPanel.superclass.constructor.apply(this, arguments);

    // 位于构造器之后,在这里你可以为当前对象新添加功能(如处理如事件)

    this.on(

        ‘click’,

        function() {

            alert(“你已点击” + this.title);

        },

        this

    );

   

工厂模式的案例中你可以在工厂方法以外的地方登记事件的处理函数。

myFirstPanel.on(

        ‘click’,

        function() {

            alert(“你已点击” + this.title);

        },

        myFirstPanel //作用域

    );

另外,除了添加listeners配置项还有其他处理监听器的方法,不过我推荐高级用户使用。

完成同一件事在Ext中有不同的方式。挑选一种你较倾向的方法。

Extending_ext_components

继承

Ext提供了这样的一个实用函数 Ext.extend (API 参考) 在EXT框架中实现类继承的机制。这赋予了你扩展任何JavaScript基类的能力,而无须对类自身进行代码的修改(这里通常指的是子类,或是从它继承的,一个基类)扩展Ext组件这是个较理想的方法。

要从一个现有的类创建出一个新类,首先要通过一个函数声明新类的构造器,然后调用新类属性所共享的扩展方法。这些共享的属性通常是方法,但是如果要在实例之间共享数据(例如,Java中的静态类变量),应该也一同声明。

JavsScript并没有提供一个自动的调用父类构造器的机制,所以你必须通过属性superclass在你的构造器中显式调用父类。第一个参数总是this,以保证构造器工作在调用函数的作用域。

MyNewClass = function(arg1, arg2, etc) {

   // 显式调用父类的构造函数

   MyNewClass.superclass.constructor.call(this, arg1, arg2, etc);

};

Ext.extend(MyNewClass, SomeBaseClass, {

  theDocument: Ext.get(document),

  myNewFn1: function() {

    // etc.

  },

  myNewFn2: function() {

   // etc.

  }

});

下面的一个例子是Ext的实际案例,用于可缩放,拖动元素,X、Y的坐标值指定了对象可在垂直、水平方向拖动的距离。

// 创建新类的构造函数

Ext.ResizableConstrained = function(el, config){

    Ext.ResizableConstrained.superclass.constructor.call(this, el, config);

};

// 扩展基类

////setXConstraint()和setYConstraint来限制拖拽范围

Ext.extend(Ext.ResizableConstrained, Ext.Resizable, {

    setXConstraint : function(left, right){

        // 得到父类的属性dd和setXConstraint的引用

        this.dd.setXConstraint(left, right);

    },

   setYConstraint : function(up, down){

     // 得到父类的属性dd和setYConstraint的引用

     this.dd.setYConstraint(up, down);

   }

});

// 创建新类的实例

var myResizable = new Ext.ResizableConstrained(‘resize-el’, {

   width: 200,

   height: 75,

   minWidth:100,

   minHeight:50,

   maxHeight:150,

   draggable:true

});

//调用新方法

myResizable.setYConstraint(0,300);

myResizable.setXConstraint(0,300);

   

Ext.Component

大多数Ext窗口小部件(如Form elements, Panels, Toolbars, ..)继承自Ext.Component(那些没有继承的将在Ext3中实现继承)。

预配置类

最简单的扩展Ext.Component的方式(或者任何继承自它的类)就是延续Ext1.X中利用Ext.extend()的做法。然而还有个差别,就是你不需要定义自己的构造函数(构造函数将由initComponent()来处理,文章后面将会讲到)。如果你所需的是定义一些自己的缺省类来重用(指的是这里和ExtJS社区作为预配置类),所有你所需要做的就是:

//定义组件Ext.some.component的预配置类MyComponent

MyComponent = Ext.extend(Ext.some.component, {

    myDefault1: ‘..’,

    myDefault2: ‘..’

});

//注册成xtype以便延迟加载

Ext.reg(‘mycomponentxtype’, MyComponent);

在以上示例中,Ext.extend()中的第二个参数对象包含的自定义参数可覆盖Ext.some.component中已经支持的缺省参数。

以上示例看上去较简单,但能够让你从程序中重构除去相当数量重复的代码,并生成可重用的对象。举个例子,你可以用预配置选项创建一个Ext.some.component的实例,代码如下:

    var myComponent = new MyComponent();

或者通过你注册过的Component XType延迟加载,下面示例作为Panel的组件项:

{..

   items: [ {xtype: ‘mycomponentxtype’} ]

..}

扩展Ext.Component

好的,虽然预配置类很有用,但是目前为止我们还没有添加任何其他的功能给继承类。我们需要覆盖一些方法来实现。这是Ext2.X精彩的地方。

Ext.Component源自1.x,但是在2.x中,它得到了扩展和加强,使它成为了整个架构中最基础的类。现在组件提供统一的组件创建、渲染、事件处理、状态维护、销毁模型,而且Ext中的每个组件,凡是需要这些特性的现在都扩展自Component。

一个可重用模板

MyComponent = Ext.extend(Ext.some.component, {

    //缺省构造参数,可被自定义设置覆盖

    propA: 1,

    initComponent: function(){

       //在组件初始化期间调用的代码

        //因为配置对象应用到了“this”,所以属性可以在这里被覆盖,或者添加新的属性

        //(如items,tools,buttons)

        Ext.apply(this, {

            propA: 3

        });

       //调用父类代码之前       

        //调用父类构造函数(必须)

        MyComponent.superclass.initComponent.apply(this, arguments);

       //调用父类代码之后

        //如:设置事件处理和渲染组件

    },

    //覆盖其他父类方法

    onRender: function(){

        //调用父类代码之前

        //调用父类相应方法(必须)

        MyScope.superclass.onRender.apply(this, arguments);

        //调用父类代码之后

    }

});

//注册成xtype以便能够延迟加载

Ext.reg(‘mycomponentxtype’, MyComponent);

var myComponent = new MyComponent({

    propA: 2

});

//或者延迟加载:

{..

  items: {xtype: ‘mycomponentxtype’, propA: 2}

..}

   

学习资料

desktop

官方网站:http://www.extjs.com/

index This page is generated by 1625

2010-09-09 19:54:11