ExtJS row widget 正确用法

最近用到ExtJS的row widget控件,踩了一个大坑,具体来说就是参照官网的示例(http://examples.sencha.com/extjs/6.2.0/examples/kitchensink/#row-widget-grid)创建好工程之后,点击表格行展开,不显示子表格,如图:

ExtJS row widget 正确用法_第1张图片

正确的显示结果:

ExtJS row widget 正确用法_第2张图片

sencha论坛上也有类似的问题,不过都没有给出正面的解决方法,像这个:

https://www.sencha.com/forum/showthread.php?316582-RowWidget-Plugin-child-Grid-data-is-not-loading

给出的处理方法是:

ExtJS row widget 正确用法_第3张图片

把orders写到companies中,这可以暂时解决问题,但不是最好的方法,不过这个答案也给了我启发。

 

下面开始分析问题,首先从基本文件说起:

在官网的示例中,一个有四个类:

175023_0ofl_1170961.png

View是一个Ext.grid.Panel(1),指定store为Companies(2),包含一个ptype为'rowwidget'的widget plugin(3),这个widget绑定了store为'{record.orders}'(4)。

ExtJS row widget 正确用法_第4张图片

这个名为Companies的store如下图:

ExtJS row widget 正确用法_第5张图片

注意proxy的url为‘/KitchenSink/Company’,访问的数据在 ext-x.x.x\build\examples\kitchensink\classic\samples\data 下的Company.js文件里,为什么这个url就可以访问到数据内,看Company.js文件最后的一段:

ExtJS row widget 正确用法_第6张图片

是因为使用了Ext.ux.ajax.SimManager.register方法注册。

接着来看Company.js中的数据:

ExtJS row widget 正确用法_第7张图片

Ext.ux.ajax.SimManager.register注册的url返回的即是companies数组。

companies数据对应Company这个model:

ExtJS row widget 正确用法_第8张图片

由于我需要从web服务器获取数据,所以把Companies这个store改成了:

ExtJS row widget 正确用法_第9张图片

这个不重要,直接往下:

到这一步,如果文件配置正确的话,显示出父表格是没有问题的。

接着来看Order这个model:

ExtJS row widget 正确用法_第10张图片

整个工程中只define了一个KitchenSink.model.Order,并没有明确指定出哪一个store的model为Order,那它是如何起作用的呢?

仔细看rowwidget的配置项,红框处的bind:

ExtJS row widget 正确用法_第11张图片

很容易猜到这个bind会让这个store和Order发生一定的关系,我们来做个测试:

把 store: '{record.orders}' 改成 store: '{record.tests}' ,然后把 'KitchenSink.model.Order' 这个model改成 'KitchenSink.model.test',重新编译执行:

ExtJS row widget 正确用法_第12张图片

可正确显示(我这个子表数据请求的服务器端没有做处理,所以返回所有的数据,这个后面会讲)。

很容易看出,store: '{record.xxx(ie)s}' 会自动绑定名为xxx的model,然后获得数据,不区分首字母大小写,xxx(ie)s代表xxx的英文复数(写错了是不行的)。

这里还有一个关键的地方,Order的companyId要指定reference,parent为Company

ExtJS row widget 正确用法_第13张图片

这个也是有讲究的,parent要设为父表格的model名,name为xxxId,xxx即父对象model名,不区分首字母大小写。

从理论上来说,配置好row widget的store就可以让row widget正常工作了,但是,为什么已经和示例文件一模一样了,Order还是不工作呢?

接下来就来说说在这个工程中最容易踩到的坑,包括上面sencha社区中的那个示例,也出现了这个问题:

注意看示例工程中Company和Order两个model有一个共同的的父类:'KitchenSink.model.Base',如果你不extend这个父类,直接extend Ext.data.Model,像我踩过的坑一样,那子列表怎么都不会显示。

ExtJS row widget 正确用法_第14张图片

之所以要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方法:

ExtJS row widget 正确用法_第15张图片

其中有对filters的处理,那row widget的proxy访问url时的参数是怎样的呢?

ExtJS row widget 正确用法_第16张图片

把最下面那个GET方法解码一下,结果是:

 /Order?_dc=1477308085906&filter=[{"property":"companyId","value":1,"exactMatch":true}]

这个filter以及filter的处理方法就使得返回的orders只包含companyId == (filter中的companyId)的数据,结果就是展开的子表格只包含选中company的数据。

 

踩了这个坑虽然很郁闷,但是也让我对ExtJS的设计思路有了更深入的理解,我这里就不求甚解地给出解决方法,至于为什么要这样,等我对ExtJS理解更深的时候再更新吧。

转载于:https://my.oschina.net/u/1170961/blog/775030

你可能感兴趣的:(ux,php)