最近用到ExtJS的row widget控件,踩了一个大坑,具体来讲就是参照官网的示例(http://examples.sencha.com/extjs/6.2.0/examples/kitchensink/#row-widget-grid)建立好工程以后,点击表格行展开,不显示子表格,如图:php
正确的显示结果:web
sencha论坛上也有相似的问题,不过都没有给出正面的解决方法,像这个:ajax
https://www.sencha.com/forum/showthread.php?316582-RowWidget-Plugin-child-Grid-data-is-not-loading数组
给出的处理方法是:服务器
把orders写到companies中,这能够暂时解决问题,但不是最好的方法,不过这个答案也给了我启发。测试
下面开始分析问题,首先从基本文件提及:ui
在官网的示例中,一个有四个类:url
View是一个Ext.grid.Panel(1),指定store为Companies(2),包含一个ptype为'rowwidget'的widget plugin(3),这个widget绑定了store为'{record.orders}'(4)。spa
这个名为Companies的store以下图:设计
注意proxy的url为‘/KitchenSink/Company’,访问的数据在 ext-x.x.x\build\examples\kitchensink\classic\samples\data 下的Company.js文件里,为何这个url就能够访问到数据内,看Company.js文件最后的一段:
是由于使用了Ext.ux.ajax.SimManager.register方法注册。
接着来看Company.js中的数据:
Ext.ux.ajax.SimManager.register注册的url返回的便是companies数组。
companies数据对应Company这个model:
因为我须要从web服务器获取数据,因此把Companies这个store改为了:
这个不重要,直接往下:
到这一步,若是文件配置正确的话,显示出父表格是没有问题的。
接着来看Order这个model:
整个工程中只define了一个KitchenSink.model.Order,并无明确指定出哪个store的model为Order,那它是如何起做用的呢?
仔细看rowwidget的配置项,红框处的bind:
很容易猜到这个bind会让这个store和Order发生必定的关系,咱们来作个测试:
把 store: '{record.orders}' 改为 store: '{record.tests}' ,而后把 'KitchenSink.model.Order' 这个model改为 'KitchenSink.model.test',从新编译执行:
可正确显示(我这个子表数据请求的服务器端没有作处理,因此返回全部的数据,这个后面会讲)。
很容易看出,store: '{record.xxx(ie)s}' 会自动绑定名为xxx的model,而后得到数据,不区分首字母大小写,xxx(ie)s表明xxx的英文复数(写错了是不行的)。
这里还有一个关键的地方,Order的companyId要指定reference,parent为Company:
这个也是有讲究的,parent要设为父表格的model名,name为xxxId,xxx即父对象model名,不区分首字母大小写。
从理论上来讲,配置好row widget的store就可让row widget正常工做了,可是,为何已经和示例文件如出一辙了,Order仍是不工做呢?
接下来就来讲说在这个工程中最容易踩到的坑,包括上面sencha社区中的那个示例,也出现了这个问题:
注意看示例工程中Company和Order两个model有一个共同的的父类:'KitchenSink.model.Base',若是你不extend这个父类,直接extend Ext.data.Model,像我踩过的坑同样,那子列表怎么都不会显示。
之因此要extend这个父类,是由于须要父类声明一个namespace,Company和Order这两个model都在这个namespace中,像在我这个工程里,model名称前面的xxx.xxx须要和namespace一致。
最后,在View中requires里添加对Order这个model的引用(若是你不是sencha cmd生成的工程,可能不须要这么写)。
ok,如今能够测试是否正常展开子表格了。
另外,补充一下 /KitchenSink/Order 返回数据的一些细节:
一样在 ext-x.x.x\build\examples\kitchensink\classic\samples\data 目录下,Order.js文件:
注意它的register方法:
其中有对filters的处理,那row widget的proxy访问url时的参数是怎样的呢?
把最下面那个GET方法解码一下,结果是:
/Order?_dc=1477308085906&filter=[{"property":"companyId","value":1,"exactMatch":true}]
这个filter以及filter的处理方法就使得返回的orders只包含companyId == (filter中的companyId)的数据,结果就是展开的子表格只包含选中company的数据。
踩了这个坑虽然很郁闷,可是也让我对ExtJS的设计思路有了更深刻的理解,我这里就不求甚解地给出解决方法,至于为何要这样,等我对ExtJS理解更深的时候再更新吧。