天天看点

[ExtJS]设置级联菜单的默认值

一、问题

    1.1  截图

       

    1.2  代码

      1.2.1  前端代码

    <script type="text/javascript">

        //

        function ExtStore(url)

        {

            return new Ext.data.Store({

                proxy: new Ext.data.HttpProxy({

                    url: url

                }),

                reader: new Ext.data.JsonReader({

                    totalProperty: 'count',

                    root: 'result'

                },

                [

                    { name: 'Id' },

                    { name: 'Name' }

                ])

            });

        }

        Ext.onReady(function() {

            Ext.QuickTips.init();

            Ext.form.Field.prototype.msgTarget = 'side';

            var store1 = ExtStore('combox.aspx?method=GetProvinces');

            var store2 = ExtStore('combox.aspx?method=GetCitys');

            var combo2 = ComboBox('combo2','二级菜单',store2);

            var combo1 = new Ext.form.ComboBox({

                mode: 'remote',

                fieldLabel:'一级菜单',

                name:'combo1',

                editable : false,

                typeAhead: true,

                triggerAction: 'all',

                displayField:'Name',

                valueField:'Id',

                selectOnFocus:true,

                store:store1,

                listeners: {

                    'select': function(combo, record){

                        var id = record.get('Id');

                        if(id)

                        {

                            //清空二级菜单选项

                            combo2.setRawValue('');

                            store2.proxy = new Ext.data.HttpProxy({

                                url:String.format('combox.aspx?method=GetCitys&Province={0}',id)

                            });

                            store2.load();

                        }

                    }

                }

            var form1 = new Ext.FormPanel({

                layout: 'form',

                autoHeight: true,

                frame: true,

                renderTo: Ext.getBody(),

                title: '<center style="curor:hand" onclick="window.location.reload();">表单控件</center>',

                style: 'margin-left:auto;margin-right:auto;width:500px;margin-top:8px;',

                //设置标签对齐方式

                labelAlign: 'right',

                //设置标签宽

                labelWidth: 170,

                //设置按钮的对齐方式

                buttonAlign:'center',

                //默认元素属性设置

                defaults:{  width:180   },

                items: [

                    combo1,

                    combo2

                ]

            //加载数据

            Ext.Ajax.request({

                url: 'combox.aspx?method=Detail',

                method: 'GET',

                callback: function (options, success, response) {

                    if(success && response.status == 200){

                        //将值批量赋值

                        form1.form.setValues(Ext.util.JSON.decode(response.responseText))

            }); 

        });

    </script>

      1.2.2  后台代码

    static IList<Combox> Provinces = new List<Combox>();

    static IDictionary<int, Combox> Citys = new Dictionary<int, Combox>();

    static combox()

    {

        Provinces.Add(new Combox() { Id = 1, Name = "湖南省" });

        Provinces.Add(new Combox() { Id = 2, Name = "广东省" });

        Citys.Add(1, new Combox()

            Id = 1,

            Name = "长沙市"

        Citys.Add(2, new Combox()

            Name = "岳阳市"

        Citys.Add(3, new Combox()

            Id = 2,

            Name = "深圳市"

        Citys.Add(4, new Combox()

            Name = "珠海市"

    }

    protected void Page_Load(object sender, EventArgs e)

    /// <summary>

    /// 获取所有省份数据

    /// </summary>

    /// <returns></returns>

    public void GetProvinces()

        Response.Write(new StringBuilder().Append("{count:")

            .Append(Provinces.Count)

            .Append(",result:")

            .Append(JavaScriptConvert.SerializeObject(Provinces))

            .Append('}')

            .ToString());

    /// 获取省下面的市区数据

    public void GetCitys()

        IList<Combox> result = new List<Combox>();

        int Province = Convert.ToInt32(Request.QueryString["Province"]);

        foreach (KeyValuePair<int, Combox> data in Citys)

            if (data.Value.Id == Province)

                result.Add(new Combox() { Id = data.Key, Name = data.Value.Name });

            .Append(result.Count)

            .Append(JavaScriptConvert.SerializeObject(result))

    public override string Detail()

        IDictionary<string, int> result = new Dictionary<string, int>();

        result.Add("combo1", 2);

        result.Add("combo2", 2);

        return JavaScriptConvert.SerializeObject(result);

    class Combox

        public int Id { get; set; }

        public string Name { get; set; }

    1.3  代码说明

      1.3.1  后台代码中使用的数据仅用测试用

      1.3.2  意图:加载的时候就默认选择广东省——珠海市

二、问题分析 

    ComboBox延迟加载导致。

三、解决办法

    2.1  让ComboBox赋值后显示对应的Name,而不是Id

      在Ext.Ajax.request执行前加一句“store1.load();”即可。

    2.2  ComboBox级联赋值

      级联赋值可没这么简单了,需要手动触发事件,这里尝试了很长时间才出结果。

      2.2.1  第一步,手动触发一级菜单选择事件

            store1.load();

                        var comboValue1 = combo1.getValue();

                        var selectRecord;

                        store1.each(function(record){

                            if(record.data.Id == comboValue1)

                                selectRecord = record;

                        });

                        combo1.fireEvent('select',combo1,selectRecord);

        这里发现手动触发得自己传入record的参数,不然里面去不到值。

      2.2.2  修改级联

                            store2.load({

                                callback :function(r,options,success){

                                    if(success){

                                        if(IsLoad)

                                        {

                                            combo2.setValue(comboValue2);

                                            IsLoad = false;

                                        }

                                    }

                                }

        代码说明:

          a).  IsLoad是全局变量,用来控制仅设置一次默认值

          b).  很容易又会犯触发菜单一就直接给菜单二赋值的错,注意这里因为菜单二还没有加载完,所有如果直接在触发事件后面写赋值,出来仍然是数字。

      2.2.3  最终效果图

        

四、代码下载

五、维护

    5.1  2010-6-13

      此文对本文的问题有所启发:http://hi.baidu.com/pure_adoration/blog/item/7146f0264608730a908f9d5d.html

六、转载保留

    博客园:http://www.cnblogs.com/

      农民伯伯:http://over140.cnblogs.com/

继续阅读