从extjs的ComboBox探究form的提交
作者:yinwm
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明。
今天又差点被extjs搞死了,好吧,我承认是已经搞死了。
具体的事情是这样的,我有一个页面是填写数据,就是一个Form啊,里面有下拉列表,使用extjs里面的ComboBox,然后就发现鸟几个诡异的事情。
- 一旦选中了某一个选项,就无法选择其他的了,因为下拉选项里面只有这个当前选中的备选项。
- 无论我怎么提交,提交过去的都是显示的选项而不是对应的value。
第一个问题抄了别人的代码看明白了,原来是在设置ComboBox的时候需要把参数triggerAction设置成为’all’,它默认的是’query’。这是表示我下面显示的是全部内容还是根据当前ComboBox里面输入的内容进行筛选的内容。
下面来说说第二个问题,折腾了我几个小时的问题。
我们看一下原来的<select>的写法,其中的选项<option value=”value”>Text</option>。给用户看到的是Text,而post到server的是value。但是extjs的ComboBox呢?我尝试了n次,他都是把Text给我传回去了。翻文档,google,也没有个所以然,最后继续祭出hack大法。
用firebug看一下生成的页面,ComboBox是由一个input和一个div组成的,这个input的名字就是你在ComboBox里面设定的名字,随着你的选择,你选中项的Text也就写进了这个input。也就是说明在提交的时候,form用的是这个内容。这里面有两个疑惑我的问题。
- 文档上说默认情况下FormPanel(其实是FormPanel内置的BasicForm)会使用BasicForm的Action方法进行Ajax提交。
- 文档上说ComboBox的值,由制定的valueField从Store里面获取。
看到这两个文档说,你会想到什么,至少我是下意识的想到,form提交的时候,遍历他的所有的孩子,然后获取各自的value,组织一下,用Ajax post到服务器。多make sense。Bingo,恭喜你,跟我一样,答错了。
我从BasicForm的submit一路寻找到底,才发现他到底怎么做的。我说说,你听听,在想当初。
- submit的方法都是归并到doAction方法,然后根据你是submit,再去寻找Ext.form.Action.Submit类的run方法。
- Ext.form.Action.Submit.run里面有一个方法是getParams用来拼接参数,这是继承自Ext.form.Action.getParams
- Ext.form.Action.getParams调用Ext.lib.Ajax.serializeForm方法。在这里我却找了半天没找到这个方法,因为我是直接grep Ext.lib.Ajax.serializeForm,未果,全是调用。最后grep Ext.lib.Ajax,才发现在每一个adapter里面有这么一个类,进去才找到serializeForm方法。
- 因为我使用的adapter是ext-base,所以分析他的serializeForm方法,是根据传入的form遍历所有的孩子
- 恍然大悟,原来拼接的参数也是从form里面抠出来的,而不是各个组件自己维护的value。
既然这样,那就得从ComboBox如何能够正确的生成input下手了。查看Ext.form.ComboBox.onRender方法,对一个叫做hiddenName的变量进行判断,然后根据判断的结果生成input。并且里面的数据是取自hiddenField的值,而hiddenField的值是在定义了hiddenValue时候使用,没定义的时候使用ComboBox的value,所以也就是ComboBox的valueField定义的。
修改代码,在生成ComboBox的时候,添加hiddenName参数,这时候生成的form终于对了,post到server的内容也对了。
太不容易了。
这时候我还有一个疑问,根据文档,如果我在生成BasicForm的时候,给定参数standardSubmit为true,那么就会使用默认的DOM的form.submit()方法,也就是标准的刷新页面的提交方法。但是这个和非standardSubmit的区别仅仅是方法的不同,而不是一个原生的(native)的提交方法和Ajax(自组织value)的提交方法。
对extjs的建议
- 对文档和名称再标准化一些,至少要比较make sense吧(也许是以前我自己写UI框架时候中毒太深吧)
- 最好给一个设计的文档出来,要知道OO的代码看上去是比较费劲的
- ComboBox很不错,就是文档糟糕了点,至少例子里面的注释多点好伐