A JavaScript Fancier

伟大的javascript技术研究中...

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  304 随笔 :: 0 文章 :: 479 评论 :: 0 Trackbacks


更新Ext ComboBox的列表项,直接通过更新其Store即可,而且可以通过Filter对store数据进行过滤只显示符合特定条件的列表项。
今天项目正好需要这个了,页面4个ComboBox的列表随着页面操作需要不断更新,我采用的方法也正是filter,本来以为一个很简单的问题,但整整郁闷了我两个多小时,开始发现filter之后虽然store的内容已经发生了变化,但ComboBox的列表项却仍然是原来的,偶以为是自己程序那个地方出错了,结果查了半天也没有找到什么错误。

后来测试突然发现只是第一次点击显示ComboBox的时候没有显示过滤后的内容,而从第二次开始每次都能获显示flter后的内容。
这个问题真是怪了,我猜想应该是EXT本身的问题,开始只是想触发一个expand事件,但发现问题并不那么简单,花费半个小时也没有想到好的办法,只好到Ext Forum上求助了,先search了一下ComboBox Filter,发现了已经有很多人遇到了与我同样的问题,看来真的是Ext的问题了,看了几篇帖子,找到了一个比较有效的解决办法:filter之后删除原store的数据快照。
如:

store.filter();
delete store.snapshot;
马上试了一下还真可以,兴奋了半天之后却又遇到了另一个问题,即store.clearFilter不能还原到原来的数据了。思考了一下应该是store.snapshot保存了最原始的数据,这样一delete肯定就找不到原始数据了,因此也就不能恢复了。这可够郁闷,删也不是不删也不是!
继续思考,如果我把它的snapshot保存起来,需要用clearFilter恢复数据时再把它的snapshot给还原了岂不就解决了吗?经过测试,果真成功!

为了使用方便、降低重复代码量,偶对comboBox进行了简单的封装,除了解决上面filter的问题,还实现了通过document.forms[0].combox.value获取和设定comboBox的功能,通过选择ComboBox的列表值会同步更新form表单中combox的值。

使用方法示例:

html:
<form name="testFrm">
<input type="text" name="userlList"  id="combox" width="150" />
</form>

JS:
var data=[[1,'用户一'],[2,'用户二']];
var combox=new makeCombo('combox',data,'用户列表');

//获取userList的值
var curValue=document.forms['testForm'].userList.value;
//设定userList当前值
document.forms['testForm'].userList.value=2;

封装代码:
/**
* 根据数据生成combox到指定的位置
* id:容器,data:数据,text:文本 width:ComboBox的宽度,默认为所绑定元素的宽度
*/
function makeCombo(id,data,text,width){
    
var container=Ext.get(id);
    
if(!container)return;
    
var realInput;  //保存值的input
    return new Ext.form.ComboBox({
        store: 
new Ext.data.SimpleStore({
            
//解决filter第一次无效的bug,保存原数据快照到另一个变量
            listeners:{datachanged:function(){if(!this.mySnap)this.mySnap=this.snapshot;delete this.snapshot}},
          fields: ['value', 'text'],
          data:data
||[]
      }),
        editable:
false,
        valueField:'value',
        displayField: 'text',
        typeAhead: 
true,
        lazyInit: 
false,
        width:width
||container.getComputedWidth(),
        mode: 'local',
        listeners:{
            render:
function(_this){
                realInput
=Ext.DomHelper.insertAfter(container,{tag: 'input',type:'hidden',name:_this.getName(),value:_this.getValue()}) 
                realInput.onpropertychange
=function(){_this.setValue(this.value)};  //真实表单联动模拟表单
                container.dom.removeAttribute('name');
                _this.clearFilter
=function(){   //扩展一个方法还原store
                    _this.store.snapshot=_this.store.mySnap;
                    _this.store.clearFilter();
                }
            },
            select:
function(combo,rec,index){   //模拟表单联动真实表单
                realInput.value=rec.get('value');
            }
        },
        triggerAction: 'all',
        emptyText: 
"请选择"+(text||''),
        selectOnFocus: 
true,
        applyTo: container
    });
}
posted on 2008-06-02 09:01 Yemoo'S JS Blog 阅读(4452) 评论(4)  编辑 收藏 引用 所属分类: Js框架组件

评论

# re: 解决Ext2.0中ComboBox执行Filter第一次无效的问题 2008-06-02 09:02 Yemoo'S JS Blog
还有一种更简单的办法:
lastQuery:''
就可以解决执行Filter第一次无效的问题了
  回复  更多评论
  

# re: 解决Ext2.0中ComboBox执行Filter第一次无效的问题 2009-06-18 16:41 xfan
lastQuery:''   回复  更多评论
  

# re: 解决Ext2.0中ComboBox执行Filter第一次无效的问题 2009-07-28 17:06 Norri
Ext3中该问题依然存在,
lastQuery:'' 的方法也有问题,反正我一加上这句就query不到选项了。我的解决方法是给combo添加如下的listener

listeners:{
'afterrender':function(c){
c.doQuery('',true);//先query一次
},
'expand':function(c){
c.getStore().filter('code',/GUZ\S/);//再执行filter
}
},  回复  更多评论
  

# re: 解决Ext2.0中ComboBox执行Filter第一次无效的问题 2014-10-14 11:25 学习着
var rightupstore = new Ext.data.JsonStore({
root:'root',
fields:[
{name:'dimcod'},
{name:'dimnam'},
{name:'valflg'},
{name:'collen'},
{name:'dimtyp'},
{name:'diccod'},
{name:'dspcol'},
{name:'valcol'},
{name:'calflg'},
{name:'ctldimcmp'},
{name:'dimdsptyp'},
{name:'slcflg'},
{name:'varflgstr'},
{name:'rltflg'},
{name:'dimlvl'},
{name:'mltflg',type:'boolean'},
{name:'datflg'},
{name:'coldattyp'},
{name:'editFlg'},
],
filterOnLoad:true,
filters:[{property:'editFlg', value:'3'}
}]就是过滤不掉怎么办呢,是什么错误啊  回复  更多评论
  

只有注册用户登录后才能发表评论。