ExtJS 设置级联菜单的默认值

  前言

   ExtJS在修改这样的页面上赋值是很方便的,在正文中1.2.1代码中可以看出,一行代码就可以搞定,但这是对于普通控件而言,如文本框。对于ComboBox可没这么简单...

  版本

  Ext JS Library 3.0.0

  正文

  一、问题

    1.1  截图

      

ExtJS 设置级联菜单的默认值

    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()

  {

  Id = 1,

  Name = "岳阳市"

  });

  Citys.Add(3, new Combox()

  {

  Id = 2,

  Name = "深圳市"

  });

  Citys.Add(4, new Combox()

  {

  Id = 2,

  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());

  }

  /// <summary>

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

  /// </summary>

  /// <returns></returns>

  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 });

  }

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

  .Append(result.Count)

  .Append(",result:")

  .Append(JavaScriptConvert.SerializeObject(result))

  .Append('}')

  .ToString());

  }

  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();”即可。

      

ExtJS 设置级联菜单的默认值

    2.2  ComboBox级联赋值

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

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

  

复制代码 代码如下:

  store1.load();

  //加载数据

  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))

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

  四、代码下载

  /201006/yuanma/combox2010-6-12.rar

  结束

  注意代码中的如PageBase、 ComboBox('combo2','二 级菜单',store2)之类的代码可以在我以前的文章里面找得到说明。遇到问题除了抱怨还可以选择消灭,那种解决后的快感是非常深刻的,这个问题很早就解决了,一直没时间写,现在仍然记得清晰 :)