最近用到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理解更深的時候再更新吧。