天天看點

[ExtJS]設定級聯菜單的預設值

前言

   ExtJS在修改這樣的頁面上指派是很友善的,在正文中1.2.1代碼中可以看出,一行代碼就可以搞定,但這是對于普通控件而言,如文本框。對于ComboBox可沒這麼簡單...

版本

  Ext JS Library 3.0.0

正文

  一、問題

    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  最終效果圖

        

  四、代碼下載下傳

    /Files/over140/2010/6/combox2010-6-12.rar

  五、維護

    5.1  2010-6-13

      此文對本文的問題有所啟發:http://hi.baidu.com/pure_adoration/blog/item/7146f0264608730a908f9d5d.html

  六、轉載保留

    部落格園:http://www.cnblogs.com/

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

結束

  注意代碼中的如PageBase、 ComboBox('combo2','二 級菜單',store2)之類的代碼可以在我以前的文章裡面找得到說明。遇到問題除了抱怨還可以選擇消滅,那種解決後的快感是非常深刻的,這個問題很早就解決了,一直沒時間寫,現在仍然記得清晰 :)

繼續閱讀