grid.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import _ from 'lodash'
  2. import {grid} from '../Defaults'
  3. import {baseConfig} from "./base";
  4. import {invokeMethod} from "../utils";
  5. import {lookupFn, lookupScope} from "../lib/lib";
  6. import {serverInvokeUrlTransform} from "../lib/config";
  7. export default function () {
  8. Ext.define('Yvan.Grid', {
  9. extend: 'Ext.grid.Panel',
  10. xtype: 'yvgrid',
  11. constructor(config) {
  12. const me = this
  13. const {dataSource} = config
  14. const newConfig = _.defaultsDeep({
  15. // 强制性属性
  16. }, baseConfig(config, 'row-item'), config, grid)
  17. if (_.isPlainObject(dataSource) && dataSource.method === 'invoke') {
  18. newConfig.store = {
  19. autoLoad: newConfig.autoLoad,
  20. remoteSort: newConfig.remoteSort,
  21. remoteFilter: newConfig.remoteFilter,
  22. proxy: {
  23. type: 'jsonAjax',
  24. $owner: me,
  25. url: serverInvokeUrlTransform(dataSource.url),
  26. extraParams: dataSource.params,
  27. reader: {
  28. type: 'json',
  29. rootProperty: 'data',
  30. totalProperty: 'pagination.total',
  31. successProperty: 'success',
  32. messageProperty: 'msg'
  33. }
  34. },
  35. listeners: {
  36. load: function (store, records, successful, operation) {
  37. me.fireEvent('dataLoadComplete', me, successful, records);
  38. }
  39. }
  40. }
  41. }
  42. const buttons = [
  43. {
  44. xtype: 'button',
  45. tooltip: '导出Excel',
  46. iconCls: 'x-fa fa-file-excel-o'
  47. },
  48. {
  49. xtype: 'button',
  50. iconCls: 'x-fa fa-columns',
  51. tooltip: '自适应宽度',
  52. listeners: {
  53. click: this.autoSizeColumns
  54. }
  55. },
  56. {
  57. xtype: 'button',
  58. tooltip: '清空筛选',
  59. iconCls: 'x-fa fa-filter',
  60. handler: this.clearFilter
  61. }
  62. ]
  63. if (newConfig.pagination) {
  64. newConfig.bbar = new Ext.PagingToolbar({
  65. pageSize: 50,
  66. displayInfo: true,
  67. store: this.store,
  68. emptyMsg: '没有记录',
  69. items: [
  70. {
  71. xtype: 'combobox',
  72. tooltip: '分页',
  73. queryMode: 'local',
  74. editable: false,
  75. allowBlank: true,
  76. labelAlign: 'right',
  77. width: 90,
  78. // labelWidth: 30,
  79. listConfig: {
  80. minWidth: null
  81. },
  82. value: 20,
  83. valueField: undefined,
  84. displayField: undefined,
  85. store: ['20', '50', '100', '200', '300'],
  86. listeners: {
  87. change: (sender, nv, ov) => {
  88. this.store.pageSize = nv;
  89. this.store.loadPage(1);
  90. }
  91. }
  92. },
  93. ...buttons
  94. ]
  95. })
  96. } else {
  97. newConfig.bbar = {
  98. xtype: 'toolbar', overflowHandler: 'menu',
  99. items: [
  100. ...buttons
  101. ]
  102. }
  103. }
  104. this.superclass.constructor.call(this, newConfig)
  105. },
  106. setData(value) {
  107. if (!this.store) {
  108. const {config} = this
  109. this.store = new Ext.data.Store({
  110. fields: getFileds(config),
  111. data: value
  112. })
  113. } else {
  114. this.store.getProxy().setData(value)
  115. this.store.load()
  116. }
  117. },
  118. reload() {
  119. const me = this
  120. const {config} = me
  121. if (config.dataSourceCallbackFn) {
  122. const scope = lookupScope(this)
  123. me.setLoading(true)
  124. config.dataSourceCallbackFn.call(scope, me, {
  125. successCallback(value) {
  126. me.setData(value)
  127. me.setLoading(false)
  128. me.fireEvent('dataLoadComplete', me, true, value);
  129. },
  130. failCallback(error) {
  131. me.setLoading(false)
  132. me.fireEvent('dataLoadComplete', me, false, error);
  133. }
  134. })
  135. }
  136. },
  137. initComponent() {
  138. const me = this
  139. const {config} = me
  140. const scope = lookupScope(this)
  141. // 转换 dataSource 属性
  142. convertDataSource(me, scope, config)
  143. this.on({
  144. afterrender(sender) {
  145. const {config} = this
  146. if (config.dataSourceCallbackFn && config.autoLoad) {
  147. me.reload()
  148. }
  149. },
  150. destory() {
  151. },
  152. })
  153. if (this.store?.proxy) {
  154. // 为 stores.proxy.buildRequest 做准备
  155. this.store.proxy.$owner = this
  156. }
  157. this.superclass.initComponent.call(this)
  158. },
  159. autoSizeColumns(sender) {
  160. const grid = sender.up('grid')
  161. // const columns = grid.columns;
  162. // for (let i = 0; i < columns.length; i++) {
  163. // const column = columns[i];
  164. // grid.getView().autoSizeColumn(column);
  165. // column.setWidth(column.getWidth() + 5);
  166. // }
  167. for (let i = 1; i < grid.headerCt.getColumnCount(); i++) {
  168. grid.headerCt.getGridColumns()[i].autoSize(i);
  169. grid.headerCt.getGridColumns()[i].setWidth(grid.headerCt.getGridColumns()[i].getWidth() + 15);
  170. }
  171. },
  172. clearFilter(sender) {
  173. sender.up('grid').filters.clearFilters();
  174. },
  175. setLoading(value) {
  176. if (value) {
  177. this.mask('读取中')
  178. } else {
  179. this.unmask()
  180. }
  181. },
  182. // reload() {
  183. // dataSourceReload(this)
  184. // },
  185. })
  186. }
  187. /**
  188. * 获取 columns 中所有的 dataIndex
  189. */
  190. function getFileds(newConfig) {
  191. const fields = []
  192. _.forEach(newConfig.columns, c => {
  193. if (c.dataIndex) {
  194. fields.push(c.dataIndex)
  195. }
  196. })
  197. return fields
  198. }
  199. function convertDataSource(sender, scope, newConfig) {
  200. if (typeof newConfig.store !== 'undefined') {
  201. // 有 store 属性的情况下,不做任何事
  202. return
  203. }
  204. if (typeof newConfig.dataSource === 'undefined') {
  205. // 没有定义 dataSource 的情况下,不做任何事
  206. return
  207. }
  208. if (_.isArray(newConfig.data)) {
  209. // 有 data 属性赋值的情况下
  210. newConfig.store = {
  211. fields: getFileds(newConfig),
  212. data: newConfig.data
  213. }
  214. delete newConfig.data
  215. return
  216. }
  217. let {dataSource} = newConfig
  218. if (typeof dataSource === 'string') {
  219. // dataSource 是字符串的情况下,找到成员函数
  220. dataSource = lookupFn(scope, dataSource)
  221. }
  222. if (typeof dataSource === 'function') {
  223. // dataSource 是函数的情况下,在 afterrender 之后进行回调
  224. newConfig.store = {
  225. fields: getFileds(newConfig),
  226. data: []
  227. }
  228. newConfig.dataSourceCallbackFn = dataSource
  229. return
  230. }
  231. throw new TypeError('无法识别的调用方法')
  232. }