精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-19
最后修改:2009-12-19
在阅读本文之前,你必须熟悉这两个流行的web开发框架-Extjs和JSF。熟悉他们基本的开发技术及基本原理。本文将简要介绍包装的过程及思想,以及Fence包装时的实例。 一、阅读本文你所需要了解的知识 在以上技术的基础上,我们开始吧! 二、将Ext组件转化成JSF的组件java类 所有的JSF自定义组件都是继承自UIComponentBase,由于我们都是输出组件,所以直接继承UIOutPut组件,以Menu的Textitem为例,生成完整的代码如下: 从代码中我们可以看出,我在生成组件的时候,放弃了Ext api中的方法和事件,只包含了config,并且生成的时候完全遵循Ext的继承逻辑结构,这样组件的属性在JSF类中将与Ext完全一致。 package ext.menu; import javax.el.ValueExpression; import javax.faces.context.FacesContext; import ext.annotation.InstanceOf; import ext.annotation.ParseConfigMode; import ext.annotation.PersistenceMode; import ext.annotation.ReferenceMode; import ext.annotation.XType; /** *Note:This java code is auto generated by abner,do not edit it. Adds a static * text string to a menu, usually used as either a heading or group separator. */ @XType("menutextitem") //ext bug @InstanceOf("Ext.menu.TextItem") @ParseConfigMode(name = "items", pmode = PersistenceMode.ParentProperty, rmode = ReferenceMode.Config) public class TextItem extends BaseItem{ public static final String COMPONENT_TYPE = "Ext.menu.TextItem"; public static final String COMPONENT_FAMILY = "Ext.menu.TextItem"; /** * * Create a new {@link TextItem} instance with default property values. * */ public TextItem() { super(); setRendererType(COMPONENT_FAMILY); } public String getFamily() { return (COMPONENT_FAMILY); } private Boolean hideOnClick; /** * True to hide the containing menu after this itemis clicked (defaults to * false) */ public Boolean getHideOnClick() { if (null != this.hideOnClick) { return this.hideOnClick; } ValueExpression _ve = getValueExpression("hideOnClick"); if (_ve != null) { return (Boolean) _ve.getValue(getFacesContext().getELContext()); } else { return null; } } /** * * Set the value of the hideOnClick property. * */ public void setHideOnClick(Boolean hideOnClick) { this.hideOnClick = hideOnClick; this.handleConfig("hideOnClick", hideOnClick); } private String itemCls; /** * The default CSS class to use for text items(defaults to "x-menu-text") */ public String getItemCls() { if (null != this.itemCls) { return this.itemCls; } ValueExpression _ve = getValueExpression("itemCls"); if (_ve != null) { return (String) _ve.getValue(getFacesContext().getELContext()); } else { return null; } } /** * * Set the value of the itemCls property. * */ public void setItemCls(String itemCls) { this.itemCls = itemCls; this.handleConfig("itemCls", itemCls); } private String text; /** * The text to display for this item (defaults to'') */ public String getText() { if (null != this.text) { return this.text; } ValueExpression _ve = getValueExpression("text"); if (_ve != null) { return (String) _ve.getValue(getFacesContext().getELContext()); } else { return null; } } /** * * Set the value of the text property. * */ public void setText(String text) { this.text = text; this.handleConfig("text", text); } private Object[] _values; public Object saveState(FacesContext _context) { if (_values == null) { _values = new Object[4]; } _values[0] = super.saveState(_context); _values[1] = hideOnClick; _values[2] = itemCls; _values[3] = text; return _values; } public void restoreState(FacesContext _context, Object _state) { _values = (Object[]) _state; super.restoreState(_context, _values[0]); this.hideOnClick = (Boolean) _values[1]; this.handleConfig("hideOnClick", this.hideOnClick); this.itemCls = (String) _values[2]; this.handleConfig("itemCls", this.itemCls); this.text = (String) _values[3]; this.handleConfig("text", this.text); } } 三、渲染组件 @XType("menutextitem") //ext bug @InstanceOf("Ext.menu.TextItem") @ParseConfigMode(name = "items", pmode = PersistenceMode.ParentProperty, rmode = ReferenceMode.Config) 通过JSF配置组件的renderer之后,在渲染器中就可以找到此组件的元数据,一看即明白:InstanceOf代表组件渲染时候的实例类,如此组件 渲染后就是 var j_id = new Ext.menu.TextItem({....});当然所有的属性就会变成ext的config。在这个过程中将会有一些复杂的处理,比喻 config类型。生成后模式,这个就主要靠ParseConfigMode来控制了。当然无法一一将其细节写出来,到时候发布源码了大家自然可以看到。 四、处理特殊重要的组件 五、Ajax的处理
.......................................................................代码片段 if (this.isTypeOf(commandBtn, "submit")) { Boolean stSubmit = form.getStandardSubmit(); if (stSubmit != null && stSubmit.booleanValue()) { String hiddenId = form.getClientId(context) + ExtFormPanelRenderer.EVENT_SUFFIX; String funBody = hiddenId + ".setValue(src.getId());"; sb.append(funBody); hiddenId = form.getClientId(context) + ExtFormPanelRenderer.VIEWSTATE_SUFFIX; funBody = hiddenId + ".setValue(Fence.getViewState());"; sb.append(funBody); } sb.append(form.getVar()); sb.append(".getForm().submit("); if (stSubmit == null || !stSubmit.booleanValue()) { sb.append(encodeFormCommandOptions(context, form, commandBtn, "submit")); } sb.append(");"); } else if (this.isTypeOf(commandBtn, "load")) { sb.append(form.getVar()); sb.append(".getForm().load("); sb.append(encodeFormCommandOptions(context, form, commandBtn,"load")); sb.append(");"); } else if (this.isTypeOf(commandBtn, "reset")) { sb.append(form.getVar()); sb.append(".getForm().reset();"); } ............................ ................. if (action != null) { if (action.getFailure() == null) action.setFailure(JSUtils.ActionFailureCallBack); if (action.getSuccess() == null) action.setSuccess(JSUtils.ActionSuccessCallBack); if (action.getUrl() == null) action.setUrl(Ext.PREFIX_RAW_VALUE + ScriptManager.AJAX_PATH); if (action.getWaitMsg() == null) action.setWaitMsg("Loading..."); params.putAll(ExtBasicRenderer.getParamList(action)); } else { action = new Submit(); action.setFailure(JSUtils.ActionFailureCallBack); action.setSuccess(JSUtils.ActionSuccessCallBack); action.setUrl(Ext.PREFIX_RAW_VALUE + ScriptManager.AJAX_PATH); action.setWaitMsg("Loading..."); } ...................................................
六、如何显示界面 <script type="text/javascript" src="/extjs/faces/abner.fence.script.js?st=1261213194245"><!--{12612165030800}-->script> 在生成的页面有这么一句,此处及包含整个页面生成的所有脚本,而脚本是通过一个Servlet输出的。到此从页面书写 一个JSF组件标签到最终生成页面的过程及完成! 包装的效果可以查看本版块帖子:http://www.iteye.com/topic/548626 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-12-19
封装成标签的话,会不会影响效率,必竟在服务端做了处理。
|
|
返回顶楼 | |
发表时间:2009-12-19
引用
封装成标签的话,会不会影响效率,必竟在服务端做了处理。
为什么会在这方面担心效率问题,我们所使用的所有框架都是在java中扩展写出来的,页面点个动作,也不知道要执行几百、几千、几万行代码,可我们还是要使用这些框架,说明什么?效率不是由于多几行代码导致的,效率往往是大数据量操作、数据库连接/操作、递归的业务运算所导致,而我们在外围做些包装和装饰,也不过区区多几十、几百行代码而已。呵呵! |
|
返回顶楼 | |
发表时间:2010-03-14
引用
本人是就地取材,使用 Ext的Xtemplate的功能生成的,呵呵,此处不赘述了
可否解釋一下怎樣用 Ext.Xtemplate 去生成 UIComponent 的代碼? 能夠自動生成就不用逐個 tag 去維護了 |
|
返回顶楼 | |
发表时间:2010-03-16
littlealan 写道
引用
本人是就地取材,使用 Ext的Xtemplate的功能生成的,呵呵,此处不赘述了
可否解釋一下怎樣用 Ext.Xtemplate 去生成 UIComponent 的代碼? 能夠自動生成就不用逐個 tag 去維護了 有很多方式的!可以用客户端javascript 去解释!可以用dom xml去做! |
|
返回顶楼 | |
发表时间:2010-03-17
還望可以說明清楚一點
首先是否用 extJS 那些 API doc 的 html files 作為 input file? 然後如何用 extJS 的 Xtemplate 去生成 java component code? Xtemplate 不是用來定義 html templates 的嗎? 可以用他來定義 java code template?
還有我見有些 annotation, e.g. import ext.annotation.XType, 不在 extJS source package 裡的, 是自定的 annotation?
希望可以放些 pseudo code/sample code 參考一下
我本身公司的系統是用 JSF 1.2 + facelets + richfaces, 現在想再用到一些 UI component 而再整合 extJS 上去, 現在正是尋找不同的整合 JSF/facelets 的方法.
|
|
返回顶楼 | |
发表时间:2010-03-17
littlealan 写道
還望可以說明清楚一點
首先是否用 extJS 那些 API doc 的 html files 作為 input file? 然後如何用 extJS 的 Xtemplate 去生成 java component code? Xtemplate 不是用來定義 html templates 的嗎? 可以用他來定義 java code template?
還有我見有些 annotation, e.g. import ext.annotation.XType, 不在 extJS source package 裡的, 是自定的 annotation?
希望可以放些 pseudo code/sample code 參考一下
我本身公司的系統是用 JSF 1.2 + facelets + richfaces, 現在想再用到一些 UI component 而再整合 extJS 上去, 現在正是尋找不同的整合 JSF/facelets 的方法.
这些annotation是自定义的。主要是在渲染阶段用来注释组件用的。JSF和facelets本身不需要整合,本来就是一个整体来着!在2.0中已经不存在facelets了,已经包含在jsf-api中了!我有个项目Fence现在基于2.0正在开发中,带有测试版本后将会开源! |
|
返回顶楼 | |
发表时间:2010-04-12
extjs doc中有很多缺漏和错误的地方,如何保证解析的准确度?
|
|
返回顶楼 | |
发表时间:2010-04-14
atian25 写道 extjs doc中有很多缺漏和错误的地方,如何保证解析的准确度?
例如? |
|
返回顶楼 | |
发表时间:2010-04-15
对比几次版本的更新就知道了,每次更新都是完善了xxx的doc.
而且通过源码可以知道里面很多属性是doc里面不会体现出来的. (别说private) 用多了自然会知道. 另外,jsf我没怎么用过,按你的说法,js是直接输出的,那事件方面的你如何处理呢? |
|
返回顶楼 | |
浏览 4200 次