使用ExtJS的一个扩展插件:Ext.ux.Multiselect,也就是列表框组件。对该组件相关处理以及数据绑定、动态设置
总结一下处理的小方法: 一、数据绑定 //创建记录类型person var person = Ext.data.Record.create([ { name: 'tValue', mapping: 1 }, { name: 'tText', mapping: 2 }, ]);//创建数据解析器 var reader = new Ext.data.ArrayReader({ id: 0 }, person);//创建HttpProxy代理 var proxy = new Ext.data.HttpProxy({ url: '/Admin/Theme.aspx?Action=ThemeList' });//创建数据集Store var store = new Ext.data.Store({ autoLoad: true, proxy: proxy, reader: reader }); .......................//若干代码 //创建Ext.ux.Multiselect组件 new Ext.ux.Multiselect({ id: "theme", name: 'theme', dataFields: ["tValue", "tText"], store: store, //或者使用如下数据: //data: [["1", "根"], ["2", "Image"], ["3", "CSS"], ["4", "JavaScript"], ["5", "resources"]], valueField: "tValue", displayField: "tText", width: 200, height: 100, legend: "主题列表" }),.......................//若干代码 二、动态设置数据项 var themeStore = Ext.getCmp('theme').store; if (themeStore != null) { var record = new Object(); record.tValue = "2"; record.tText = "3"; themeStore.add(new Ext.data.Record(record)); 其实这里的操作,仅仅是操作Ext.data.Store对象,如删除项的操作,可以查询API文档。另外,对于如下行: var themeStore = Ext.getCmp('theme').store; 不可以在渲染(render)事件中直接获取,因为在render事件中像:Ext.getCmp('theme'),是获取不到对象的(延时原因)。 解决的办法可以使用Ext.util.TaskRunner对象。其它的问题正在研究中... 三、数据项的获取 方法一: Ext.getCmp('theme').getValue(); 方法二: fPanel.getForm().getValues(false)['theme']; 注:fPanel为Multiselect所属的FormPanel对象,且此方法获取值时,必须给Multiselect定义name属性(此处为 'theme')。 方法三: listeners: { "click": function(mult, e) { var value = e.target.innerText; if (value == null || value == "") { Ext.getCmp('theme').setValue(''); return; } Ext.getCmp('theme').setValue(value); //m.store.getAt(e.target.viewIndex).data } } 注:仅限在click事件中,其实这里的e.target.innerText仅是显示的displayField字段,并不是值。而 “m.store.getAt(e.target.viewIndex).data”获取到的是最后单击行的 Record 对象,当然它包含valueField和displayField两个字段。对于如何仅获取displayField,请看下面第五点。 四、设置数据项只能单选 其实本人最初使用Multiselect的目的是想设置ComboBox更高一些,这样能浏览更多的数据元素。但是,至少到目前还没有发现 Multiselect对象有这样的一个属性来设置只能单选(源码中也没有发现),于是乎想到这样一个笨方法:获取最后一次单击的数据项,并设置 ComboBox的值为最后一次单击数据项的值,如下: new Ext.ux.Multiselect({ id: "theme", name: "theme", dataFields: ["tValue", "tText"], store: themeStore, valueField: "tValue", displayField: "tText", width: 200, height: 100, legend: "主题列表", listeners: { "click": function(mult, e) { var value = e.target.innerText; if (value == null || value == "") { Ext.getCmp('theme').setValue(''); return; } Ext.getCmp('theme').setValue(value); } } }) 注:参数e是click事件中传递的参数,而e.target.innerText就是当前单击数据项的值,该方法本人仅在IE中测试过,其它浏览器没有测试,为了解决兼容性问题,可以使用如下方法获取: "click": function(mult, e) { var values = fPanel.getForm().getValues(false)['theme']; if (values == null || values == "") { Ext.getCmp('theme').setValue(''); return; } var items = fPanel.getForm().getValues(false)['theme'].split(','); var item = items[items.length - 1]; Ext.getCmp('theme').setValue(item); } 注:fPanel为Multiselect所属为FormPanel对象,这个方法其实就是先解析Multiselect组件最后一次单击数据项的值,然后重新设置Multiselect的值为最后一次单击数据项的值即可。显然,比上一个方法更麻烦一点。 另外,其实上一个方法中,参数e有哪些属性和方法,我是测试得来的,网上有类似的获取方法,如下: function printf(obj) { var props = ""; for(var p in obj){ if(typeof(obj[p])=="function"){ //obj[p](); //获取到一个函数成员,如果非必须,注释这句,有些时候会因为这句js无法运行。 }else{ props+= p + "=" + obj[p] + "\t"; } } alert(props); } 这样,可以通过打印参数e中的成员,来测试它有哪些属性、方法等。 五、Multiselect扩展以实现获取displayField字段 Multiselect.js文件,找到如下行(3.0版本): getValue: function(valueField){ ........ }, 在之后添加如下: getText: function(valueField) { var returnArray = []; var selectionsArray = this.view.getSelectedIndexes(); if (selectionsArray.length == 0) { return ''; } for (var i = 0; i < selectionsArray.length; i++) { returnArray.push(this.store.getAt(selectionsArray).get(this.displayField)); } return returnArray.join(this.delimiter); },即可通过Ext.fly('theme').getText()获取到当前所有被选择项的displayField字段。