最近老师的项目需要对一些网页做页面改动,想想如果单纯只是改改页面,对自己的技术水平没什么促进作用。所以花了几天时间拿extjs练了下手,也算稍稍了解了extjs。之前在yui和extjs之间犹豫了一下,两个都没接触过,不过听说extjs的中文资料会比较多,所以嘛...
实现了一个学习活动管理页面,主要包括查询、分页浏览和创建功能。功能比较简单,没什么复杂逻辑,还没做完,慢慢完善吧,先把代码记录下来,不然以后又没兴趣写了。对extjs的一些功能和api不大了解,中间绕了很多弯路,代码写得有点杂乱。
/** * 作者:garlic 日期:2010-07-29 版本:1.0 博客地址:http://wisesooner.iteye.com/ * 功能描述:学习活动管理页面,主要包括查询、分页浏览、创建 备注:extjs版本为3.2.1 */ Ext.onReady(function() { Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); Ext.QuickTips.init(); // 活动类别 var aTypeCode = [['all', '全部类别'], ['forum', '讨论交流'], ['work', '上传作品'], ['vote', '投票调查'], ['question', '提问答疑']]; var typeNames=new Ext.data.Record( {all:'全部类别', forum:'讨论交流', work:'上传作品', vote:'投票调查', question:'提问答疑'} ); var store = new Ext.data.Store({ proxy : new Ext.data.HttpProxy({ url : "/lc/extjs/getData.jsp" }), autoLoad : { params : { start : 0, limit : 9 } }, baseParams : { type : 'all' },// 公共参数,pagingBar和grid可以共用 reader : new Ext.data.JsonReader({// 读取json数据 root : 'activities', totalProperty : 'count' }, Ext.data.Record.create(['aId', 'aTitle', 'aType', 'aDes', 'aTime', 'aViewUrl', 'aEditUrl', 'aDelUrl', 'uId', 'uName', 'auth'])) }); /* 以下是中间面板,包括顶部的查询和创建,底部的分页和中间的分页面板 */ // 底部工具条(分页工具条),注:把分页工具条加在分页面板中,看起来有点不好看,所以就把它放在中间面板中了 var pagingBar = new Ext.PagingToolbar({ pageSize : 9, displayInfo : true, displayMsg : '显示第 {0} 条到 {1} 条记录,一共 {2} 条', emptyMsg : '没有记录', store : store }); // 顶部工具条——创建活动按钮 var createBtn = new Ext.Button({ iconCls : 'create-btn', text : '+ 创建活动', handler:function(){aCreatePage.show();} }); // 顶部工具条——查询——活动类别选择框 var combo = new Ext.form.ComboBox({ displayField :'text' , valueField:'type', typeAhead : false, mode : 'local', triggerAction : 'all', emptyText : '请选择类别', selectOnFocus : false, editable : false, store : new Ext.data.SimpleStore({ fields : ['type','text'], data : aTypeCode }), width : 100 }); // 顶部工具条——查询——搜索按钮 var searchBtn = new Ext.Button({ iconCls : 'search-btn', handler:checkForm }); searchBtn.setTooltip('查询'); // 顶部工具条——查询——文本输入框 var searchTxt = new Ext.form.TextField({ id : 'search-name', width : 250, selectOnFocus : true, regex : /^.*\S+.*$/, // 不能为空 regexText : '活动名称不能为空' }); // 顶部工具条——查询(包含活动类别选择框、搜索按钮、文本输入框) var searchBar = new Ext.Toolbar({ id : 'search-bar', autoHeight : true }); searchBar.add('活动名称: ', searchTxt, ' ', combo, ' ', searchBtn, '->', createBtn, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' // 试了几种方式,都没办法很好地为“创建活动”按钮设置右边距,只好用这个土方法,看起来很不爽,如果大家有什么好建议,可以推荐 ); // 中间分页面板——构造不带分页工具栏的grid var grid = new Ext.grid.GridPanel({ store : store, trackMouseOver : true, disableSelection : true, loadMask : true, autoHeight : true, columnLines : true, border : false, // grid的列 columns : [{ header : "类别", dataIndex : 'aType', align : 'center', sortable : true, width : 75 }, { header : "标题", dataIndex : 'aTitle', sortable : true, width : 150, renderer : renderTitle }, { header : "简介", dataIndex : 'aDes', width : 500, renderer : renderDes }, { header : "创建时间", dataIndex : 'aTime', sortable : true, align : 'center', width : 80 }, { header : "创建者", dataIndex : 'uName', align : 'center', sortable : true, renderer : renderUserLink }, { header : "操作", dataIndex : 'aId', renderer : renderAction, align : 'center', width : 115 }], viewConfig : { forceFit : true } }); // 生成中间面板 var centerForm = new Ext.form.FormPanel({ id : 'centerForm', region : 'center', // a center region is ALWAYS required for // border layout deferredRender : false, activeTab : 0, // first tab initially active margins : '0 5 0 0', title : '活动列表 - 全部类别', autoScroll : true, bbar : pagingBar, tbar : searchBar, items : grid }); // body视图 var viewport = new Ext.Viewport({ layout : 'border', items : [new Ext.BoxComponent({ region : 'north', id : 'page-title', margins : '0 5 3 5', autoEl : { tag : 'div', html : '<h1>学习活动管理页面</h1>' } }), { region : 'west', id : 'west-panel', title : '按类别浏览', collapsible : true, margins : '0 0 0 5', autoScroll : true, width : 160, margins : '0 5 3 5', contentEl :'typeNav' }, centerForm] }); //创建活动的页面 var aCreatePage= new Ext.Window({ contentEl:'a_c_n', modal:true, draggable :false, width:700, height:400, border :false, resizable :false, plain:true, closeAction :'hide' }); var aCreateForm = new Ext.form.FormPanel({ labelWidth: 55, frame:true, labelSeparator:':', defaults: { xtype: 'textfield' }, items: [{ fieldLabel: '标题', width:450, emptyText : '请输入活动名称', regex : /^.*\S+.*$/, // 不能为空 regexText : '活动名称不能为空' }, { xtype: 'textarea', fieldLabel: '简介', width:450, height:200, emptyText : '请输入活动简介', regex : /^.*\S+.*$/, // 不能为空 regexText : '活动简介不能为空' }] }); var aCreateWindow = new Ext.Window({ title: '创建活动', draggable :true, bodyStyle: 'padding:5px;', buttonAlign: 'center', items: aCreateForm, border :false, resizable :false, closeAction :'hide', buttons: [{ text: '确定' },{ text: '取消', handler:function(){aCreateWindow.hide();} }] }); void function() { Ext.addBehaviors({ '#typeNav a@click':function(e,t){getData(Ext.get(this).getAttribute('value'));}, '#a_c_n dd@click':function(e,t){showCreateForm(Ext.get(this).getAttribute('value'));}, '#a_c_n dd@mouseenter':function(e,t){Ext.get(this).addClass('over');}, '#a_c_n dd@mouseleave':function(e,t){Ext.get(this).removeClass('over');} }); }(); //显示创建活动窗口 function showCreateForm(){ aCreatePage.hide(); aCreateWindow.show(); } //显示选择活动类型的页面 function leadToCreatePage(){ aCreatePage.show(); } function renderTitle(value, p, record) { return String .format( '<a class="alink" title="查看" href="{1}" target="_blank">{0}</a>', value, record.data.aViewUrl); } function renderAction(value, p, record) { var viewStr, editStr, delStr; viewStr = String .format( '<a class="alink" title="查看" href="{1}" target="_blank">查看</a>', value, record.data.aViewUrl); editStr = String .format( '<a class="alink" title="编辑" href="{1}" target="_blank">编辑</a>', value, record.data.aEditUrl); delStr = String .format( '<a class="alink" title="删除" href="{1}" target="_blank">删除</a>', value, record.data.aDelUrl); return viewStr + editStr + delStr; } function renderDes(value, cell) { cell.attr = 'style="white-space:normal"'; return value; } function renderUserLink(value, p, record) { return String .format( '<a class="alink" title="点击查看个人空间" href="/do/psTemplateUser?action=index&psUserId={1}" target="_blank">{0}</a>', value, record.data.uId); } function checkForm(){ var keyword=searchTxt.getValue().trim(); if(keyword==''){ Ext.Msg.show({ title:'提示', msg: '活动名称不能为空!', buttons: {ok:'确定'}, icon: Ext.MessageBox.INFO, modal:false, fn:function(){ searchTxt.setValue(''); searchTxt.focus(); } }); return false; } var type=combo.getValue()==''?'all':combo.getValue(); getData(type,keyword); } function getData(type,keyword) { if(type==undefined||typeof(type)!='string' ){ type='all'; } if(keyword==undefined||typeof(keyword)!='string' ){ keyword=''; } store.baseParams = { type : type, keyword:keyword }; store.reload({ params : { start : 0, limit : 9 } }); var title=typeNames.get(type); Ext.getCmp('centerForm').setTitle('活动列表 - '+title); } });
界面图:
问题:
1、构造store的时候,跨越调用不行,还不知道为什么
2、左侧那几个button很是烦人,能不能根据数组动态生成
3、所有页面元素都是由引擎生成,看了下生成的html代码,感觉很冗余而且很多,不知道会不会影响页面加载速度,别人调试也不大好调,快速方便和灵活性有点冲突啊
4、ie和ff显示样式有点差别,ff的字体会好看点,ie下的字体有点刺眼,不知道该怎么改
html,body {
font: normal 12px verdana;
margin: 0;
padding: 0;
border: 0 none;
overflow: hidden;
height: 100%;
letter-spacing:1px;
}
5、分页面板最右端还多出来一列,怎么回事...
6、如果分页面板高度太高的,出现竖直滚动条的同时会出现水平滚动条.....
7、构造数据模型的时候,不知道该用哪种,用数组也不方便,用record也不方便,最后两个一起上,哎,烦躁
8、formpanel内部控件不能自动调整大小,如果加了属性layout: 'fit',个别控件又会撑得太大,把其他控件都挤没了
9、怎么把Ext.window的背景色弄成白色啊....搞了老半天都不行
注意事项:
1、store有个公共属性baseParams,可以传一些动态参数,方便不同控件(如分页面板、分页工具条)调用
2、tooltip如果要生效,必须在开头写上“Ext.QuickTips.init();”
3、分页面板中每一列默认都是不换行的,可以用css控制一下 white-space:normal
4、Ext.window的关闭按钮默认是remove,如果不想remove的话,得加上属性 closeAction:'hide'
5、在标签dd中加入mouseover和mouseout事件,ie下会出现闪烁,改成mouseenter和mouseleave,ie和ff都ok
'#a_c_n dd@mouseenter':function(e,t){Ext.get(this).addClass('over');}, '#a_c_n dd@mouseleave':function(e,t){Ext.get(this).removeClass('over');}