浏览代码

dataSource.params 表达式取值
解决 reload 不生效问题

luoyifan 3 年之前
父节点
当前提交
bf341f0967
共有 5 个文件被更改,包括 173 次插入64 次删除
  1. 19 6
      src/Scope.ts
  2. 84 49
      src/controls/grid.js
  3. 2 2
      src/controls/input/search.js
  4. 3 7
      src/controls/stores.js
  5. 65 0
      src/lib/systemLib.ts

+ 19 - 6
src/Scope.ts

@@ -92,7 +92,11 @@ export class Scope {
                     }
 
                     // 调用onLoad回调
-                    that.onLoad()
+                    try {
+                        that.onLoad()
+                    } catch (e) {
+                        console.error('errorAt onLoad', e)
+                    }
 
                     // 如果vjson中配置了 afterrender ,需要恢复状态
                     invokeMethod(that.vjson.listeners?.show, that, arguments)
@@ -107,8 +111,9 @@ export class Scope {
         if (config.width === 'unset') {
             delete config.width
         }
-        const win = new Ext.Window(config);
         const holder = sender?.lookupReferenceHolder()
+        // delete config.constrain
+        const win = new Ext.Window(config);
         if (holder) {
             holder.add(win)
         }
@@ -142,7 +147,11 @@ export class Scope {
                     }
 
                     // 调用onLoad回调
-                    that.onLoad()
+                    try {
+                        that.onLoad()
+                    } catch (e) {
+                        console.error('errorAt onLoad', e)
+                    }
 
                     // 如果vjson中配置了 afterrender ,需要恢复状态
                     invokeMethod(that.vjson.listeners?.added, that, arguments)
@@ -186,7 +195,11 @@ export class Scope {
                     }
 
                     // 调用onLoad回调
-                    that.onLoad()
+                    try {
+                        that.onLoad()
+                    } catch (e) {
+                        console.error('errorAt onLoad', e)
+                    }
 
                     // 如果vjson中配置了 afterrender ,需要恢复状态
                     invokeMethod(that.vjson.listeners?.afterrender, that, arguments)
@@ -363,9 +376,9 @@ export class Scope {
  * 观察装饰器,viewModel 属性更改时触发成员方法
  * @param tplExpress tpl表达式,例如 "{form.f1}"
  */
-export function watch(tplExpress) {
+export function watch(tplExpress, deep = false) {
     return function (target, propertyKey, pd) {
-        target._addWatch(tplExpress, target[propertyKey])
+        target._addWatch({bindTo: tplExpress, deep}, target[propertyKey])
         return target[propertyKey]
     }
 }

+ 84 - 49
src/controls/grid.js

@@ -1,9 +1,9 @@
 import _ from 'lodash'
 import {grid} from '../Defaults'
 import {baseConfig} from "./base";
-import {invokeMethod} from "../utils";
 import {lookupFn, lookupScope} from "../lib/lib";
 import {serverInvokeUrlTransform} from "../lib/config";
+import {calcObject} from "../lib/systemLib";
 
 export default function () {
 
@@ -19,33 +19,6 @@ export default function () {
 
             }, baseConfig(config, 'row-item'), config, grid)
 
-
-            if (_.isPlainObject(dataSource) && dataSource.method === 'invoke') {
-                newConfig.store = {
-                    autoLoad: newConfig.autoLoad,
-                    remoteSort: newConfig.remoteSort,
-                    remoteFilter: newConfig.remoteFilter,
-                    proxy: {
-                        type: 'jsonAjax',
-                        $owner: me,
-                        url: serverInvokeUrlTransform(dataSource.url),
-                        extraParams: dataSource.params,
-                        reader: {
-                            type: 'json',
-                            rootProperty: 'data',
-                            totalProperty: 'pagination.total',
-                            successProperty: 'success',
-                            messageProperty: 'msg'
-                        }
-                    },
-                    listeners: {
-                        load: function (store, records, successful, operation) {
-                            me.fireEvent('dataLoadComplete', me, successful, records);
-                        }
-                    }
-                }
-            }
-
             const buttons = [
                 {
                     xtype: 'button',
@@ -113,37 +86,81 @@ export default function () {
             this.superclass.constructor.call(this, newConfig)
         },
 
-        setData(value) {
-            if (!this.store) {
-                const {config} = this
-                this.store = new Ext.data.Store({
-                    fields: getFileds(config),
-                    data: value
-                })
-            } else {
-                this.store.getProxy().setData(value)
-                this.store.load()
+        _setDataReal(value) {
+            const me = this
+            me.setStore(new Ext.data.Store({
+                fields: getFileds(this),
+                data: value
+            }))
+        },
+
+        /**
+         * 轻量级刷新
+         */
+        refreshData() {
+            const store = this.getStore()
+            if (store) {
+                store.reload()
             }
         },
 
-        reload() {
+        /**
+         * 重新载入数据(重新计算参数)
+         */
+        reload(reloadParams = {}) {
             const me = this
             const {config} = me
 
             if (config.dataSourceCallbackFn) {
+                // 函数请求刷新
                 const scope = lookupScope(this)
-                me.setLoading(true)
+                // me.setLoading(true)
                 config.dataSourceCallbackFn.call(scope, me, {
                     successCallback(value) {
-                        me.setData(value)
-                        me.setLoading(false)
+                        me._setDataReal(value)
+                        // me.setLoading(false)
                         me.fireEvent('dataLoadComplete', me, true, value);
                     },
                     failCallback(error) {
-                        me.setLoading(false)
+                        // me.setLoading(false)
                         me.fireEvent('dataLoadComplete', me, false, error);
                     }
                 })
+                return
+            }
+
+            // if (this.store) {
+            //     this.store.reload({aaaa: 1, bbbb: 2})
+            // }
+            const {dataSource} = config
+            if (_.isPlainObject(dataSource) && dataSource.method === 'invoke') {
+                const scope = lookupScope(me)
+
+                calcObject(scope.viewModel, dataSource.params).then(params => {
+
+                    me.setStore(new Ext.data.Store({
+                        remoteSort: config.remoteSort,
+                        remoteFilter: config.remoteFilter,
+                        proxy: {
+                            type: 'jsonAjax',
+                            $owner: me,
+                            url: serverInvokeUrlTransform(dataSource.url),
+                            extraParams: _.defaultsDeep({}, reloadParams, params),
+                            reader: {
+                                type: 'json',
+                                rootProperty: 'data',
+                                totalProperty: 'pagination.total',
+                                successProperty: 'success',
+                                messageProperty: 'msg'
+                            }
+                        },
+                        listeners: {
+                            load: function (store, records, successful, operation) {
+                                me.fireEvent('dataLoadComplete', me, successful, records);
+                            }
+                        }
+                    }))
+                })
             }
         },
 
@@ -158,8 +175,17 @@ export default function () {
             this.on({
                 afterrender(sender) {
                     const {config} = this
-                    if (config.dataSourceCallbackFn && config.autoLoad) {
-                        me.reload()
+                    if (config.autoLoad) {
+                        if (config.dataSourceCallbackFn) {
+                            me.reload()
+                            return
+                        }
+
+                        const {dataSource} = config
+                        if (_.isPlainObject(dataSource) && dataSource.method === 'invoke') {
+                            me.reload()
+                            return
+                        }
                     }
                 },
                 destory() {
@@ -249,14 +275,23 @@ function convertDataSource(sender, scope, newConfig) {
 
     if (typeof dataSource === 'function') {
         // dataSource 是函数的情况下,在 afterrender 之后进行回调
-        newConfig.store = {
+        newConfig.store = new Ext.data.Store({
             fields: getFileds(newConfig),
-            data: []
-        }
+            // data: [],
+            autoLoad: true,
+            proxy: {
+                type: 'memory',
+                data: [],
+                // reader: {
+                //     type: 'json',
+                //     rootProperty: 'users'
+                // }
+            }
+        })
         newConfig.dataSourceCallbackFn = dataSource
         return
     }
 
 
-    throw new TypeError('无法识别的调用方法')
+    // throw new TypeError('无法识别的调用方法')
 }

+ 2 - 2
src/controls/input/search.js

@@ -101,7 +101,7 @@ export default function () {
                      * }
                      */
                     if (_.isPlainObject(lookup)) {
-                        const parentScope = sender.lookupViewModel().yvanScope
+                        const parentScope = lookupScope(sender)
 
                         _.forOwn(lookup, (value, key) => {
                             if (!key || key === 'value') {
@@ -161,7 +161,7 @@ export default function () {
             const {lookup} = config
 
             if (_.isPlainObject(lookup)) {
-                const parentScope = sender.lookupViewModel().yvanScope
+                const parentScope = lookupScope(sender)
 
                 _.forOwn(lookup, (value, key) => {
                     if (!key || key === 'value') {

+ 3 - 7
src/controls/stores.js

@@ -1,6 +1,7 @@
 import _ from 'lodash'
 import $ from 'jquery'
 import {lookupScope} from "../lib/lib";
+import {tplExpress, calcObject} from 'src/lib/systemLib';
 
 export default function () {
 
@@ -58,13 +59,8 @@ export default function () {
                 delete gridParam.filter
             }
 
-            const extraParams = me.extraParams
-            _.forOwn(extraParams, (value, key) => {
-                if (typeof value === 'function') {
-                    value = value.call(scope, scope)
-                }
-                extraParams[key] = value
-            })
+            // 被 grid.constructor 作为方法存在
+            const extraParams = _.cloneDeep(me.getExtraParams())
             const params = _.defaultsDeep(gridParam, extraParams)
 
             // var request = this.superclass.buildRequest.apply(this, arguments);

+ 65 - 0
src/lib/systemLib.ts

@@ -0,0 +1,65 @@
+/**
+ * 对某个表达式进行求值
+ * @param viewModel 数据对象
+ * @param express
+ */
+export function tplExpress(viewModel, express) {
+    if (viewModel.expressionRe.test(express)) {
+        // If we have '{foo}' alone it is a literal 简单表达式
+        express = express.substring(1, express.length - 1);
+        return viewModel.get(express)
+
+    } else {
+        let ret = undefined
+        viewModel.bind(express, function (v) {
+            ret = v
+            debugger
+        })
+        // Ext.app.bind.TemplateBinding
+        debugger
+    }
+}
+
+/**
+ * 对多个表达式进行求值. 异步回调的方式返回
+ *      {
+ *          a: 1,
+ *          b: '{someBind}',
+ *          c: ['a', 'b', 'c'],
+ *          d: ['a', 'b', '{someBind}'],
+ *          e: {
+ *              y: 1,
+ *              z: 2
+ *          },
+ *          f: {
+ *              y: 1,
+ *              z: '{someBind}'
+ *          }
+ *      }
+ *
+ *      // Will produce
+ *      {
+ *          b: value,
+ *          d: ['a', 'b', value],
+ *          f: {
+ *              y: 1,
+ *              z: value
+ *          }
+ *      }
+ * @param viewModel scope.viewModel对象
+ * @param paramObject 求值对象
+ */
+export function calcObject(viewModel, paramObject) {
+    // new Ext.app.bind.Multi({a:'1',b:'ddd{query.WH_ID}'},currentScope.viewModel,function(v){console.log(v)},currentScope, {single: true})
+    return new Promise(resolve => {
+        const schedule = new Ext.app.bind.Multi(
+            paramObject,
+            viewModel,
+            (ret) => {
+                schedule.destroy()
+                resolve(ret)
+            },
+            viewModel,
+            {single: true})
+    })
+}