|
@@ -0,0 +1,262 @@
|
|
|
+import _ from 'lodash'
|
|
|
+import {tree} from '../Defaults'
|
|
|
+import {baseConfig} from "./base";
|
|
|
+import {lookupFn, lookupScope} from "../lib/lib";
|
|
|
+import {serverInvokeUrlTransform} from "../lib/config";
|
|
|
+import {calcObject, calcObjectFlat, invokeServer} from "../lib/systemLib";
|
|
|
+
|
|
|
+export default function () {
|
|
|
+ Ext.define('Yvan.Tree', {
|
|
|
+ extend: 'Ext.tree.Panel',
|
|
|
+ alias: 'widget.yvtree',
|
|
|
+ xtype: 'yvtree',
|
|
|
+
|
|
|
+ constructor(config) {
|
|
|
+ const newConfig = _.defaultsDeep({
|
|
|
+ // 强制性属性
|
|
|
+
|
|
|
+ }, baseConfig(config, 'row-item'), config, tree)
|
|
|
+
|
|
|
+ this.superclass.constructor.call(this, newConfig)
|
|
|
+ },
|
|
|
+
|
|
|
+ initComponent() {
|
|
|
+ const me = this
|
|
|
+ const {config} = me
|
|
|
+ const scope = lookupScope(this)
|
|
|
+
|
|
|
+ if (!window["IS_DESIGN_MODE"]) {
|
|
|
+ // 转换 dataSource 属性
|
|
|
+ convertDataSource(me, scope, config)
|
|
|
+ }
|
|
|
+
|
|
|
+ this.superclass.initComponent.call(this)
|
|
|
+
|
|
|
+ this.on({
|
|
|
+ afterrender(sender) {
|
|
|
+ const me = this
|
|
|
+ const {config} = this
|
|
|
+ const {dataSource} = config
|
|
|
+
|
|
|
+ if (config.autoLoad) {
|
|
|
+ if (config.dataSourceCallbackFn) {
|
|
|
+ me.reload()
|
|
|
+
|
|
|
+ } else if (_.isPlainObject(dataSource) && dataSource.method === 'invoke') {
|
|
|
+ me.reload()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ _setDataReal(value) {
|
|
|
+ const me = this
|
|
|
+ // me.setStore(new Ext.data.TreeStore({
|
|
|
+ // root: {
|
|
|
+ // expanded: true,
|
|
|
+ // // children: value
|
|
|
+ // children: [
|
|
|
+ // {
|
|
|
+ // id: '1', text: 'A',
|
|
|
+ // children: [
|
|
|
+ // {id: '1', text: 'A',},
|
|
|
+ // {id: '2', text: 'B'},
|
|
|
+ // ]
|
|
|
+ // },
|
|
|
+ // {id: '2', text: 'B'},
|
|
|
+ // ]
|
|
|
+ // }
|
|
|
+ // }))
|
|
|
+ me.store.setRoot({
|
|
|
+ expanded: true,
|
|
|
+ children: value
|
|
|
+ })
|
|
|
+ // me.store = new Ext.data.TreeStore({
|
|
|
+ // root: {
|
|
|
+ // expanded: true,
|
|
|
+ // // children: value
|
|
|
+ // children: [
|
|
|
+ // {
|
|
|
+ // id: '1', text: 'A',
|
|
|
+ // children: [
|
|
|
+ // {id: '1', text: 'A',},
|
|
|
+ // {id: '2', text: 'B'},
|
|
|
+ // ]
|
|
|
+ // },
|
|
|
+ // {id: '2', text: 'B'},
|
|
|
+ // ]
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重新载入数据(重新计算参数)
|
|
|
+ */
|
|
|
+ reload(reloadParams = {}) {
|
|
|
+ const me = this
|
|
|
+ const {config} = me
|
|
|
+
|
|
|
+ if (config.dataSourceCallbackFn) {
|
|
|
+ // 函数请求刷新
|
|
|
+ const scope = lookupScope(this)
|
|
|
+ // me.setLoading(true)
|
|
|
+ config.dataSourceCallbackFn.call(scope, me, {
|
|
|
+ successCallback(value) {
|
|
|
+ me._setDataReal(value)
|
|
|
+ // me.setLoading(false)
|
|
|
+ me.fireEvent('dataLoadComplete', me, true, value);
|
|
|
+ },
|
|
|
+ failCallback(error) {
|
|
|
+ // me.setLoading(false)
|
|
|
+ me.fireEvent('dataLoadComplete', me, false, error);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const {dataSource} = config
|
|
|
+ if (_.isPlainObject(dataSource) && dataSource.method === 'invoke' && !window["IS_DESIGN_MODE"]) {
|
|
|
+ const scope = lookupScope(me)
|
|
|
+
|
|
|
+ const params = calcObjectFlat(scope.viewModel.data, _.defaultsDeep({}, reloadParams, dataSource.params),)
|
|
|
+ me.setLoading(true)
|
|
|
+ invokeServer(dataSource.url, params)
|
|
|
+ .then(res => {
|
|
|
+ me._setDataReal(res.data)
|
|
|
+ me.fireEvent('dataLoadComplete', me, res)
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ me.setLoading(false)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ filterByText(text) {
|
|
|
+ this.filterBy(text, 'text');
|
|
|
+ },
|
|
|
+
|
|
|
+ filterBy(text, by) {
|
|
|
+ this.clearFilter();
|
|
|
+ const view = this.getView(),
|
|
|
+ me = this,
|
|
|
+ nodesAndParents = [];
|
|
|
+ this.getRootNode().cascadeBy(function (tree, view) {
|
|
|
+ let currNode = this;
|
|
|
+
|
|
|
+ if (currNode && currNode.data[by] && currNode.data[by].toString().toLowerCase().indexOf(text.toLowerCase()) > -1) {
|
|
|
+ me.expandPath(currNode.getPath());
|
|
|
+ while (currNode.parentNode) {
|
|
|
+ nodesAndParents.push(currNode.id);
|
|
|
+ currNode = currNode.parentNode;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, null, [me, view]);
|
|
|
+ this.getRootNode().cascadeBy(function (tree, view) {
|
|
|
+ var uiNode = view.getNodeByRecord(this);
|
|
|
+ if (uiNode && !Ext.Array.contains(nodesAndParents, this.id)) {
|
|
|
+ Ext.get(uiNode).setDisplayed('none');
|
|
|
+ }
|
|
|
+ }, null, [me, view]);
|
|
|
+ },
|
|
|
+
|
|
|
+ clearFilter() {
|
|
|
+ const view = this.getView();
|
|
|
+ this.getRootNode().cascadeBy(function (tree, view) {
|
|
|
+ var uiNode = view.getNodeByRecord(this);
|
|
|
+ if (uiNode) {
|
|
|
+ Ext.get(uiNode).setDisplayed('table-row');
|
|
|
+ }
|
|
|
+ }, null, [this, view]);
|
|
|
+ },
|
|
|
+
|
|
|
+ root: [],
|
|
|
+ rootVisible: false,
|
|
|
+ tbar: [
|
|
|
+ {
|
|
|
+ xtype: 'trigger',
|
|
|
+ triggerCls: 'x-form-clear-trigger',
|
|
|
+ onTriggerClick(sender) {
|
|
|
+ sender.setValue('');
|
|
|
+ const scope = sender.up("yvtree")
|
|
|
+ scope.clearFilter()
|
|
|
+ },
|
|
|
+ flex: 1,
|
|
|
+ emptyText: '搜索过滤',
|
|
|
+ enableKeyEvents: true,
|
|
|
+ listeners: {
|
|
|
+ keyup: {
|
|
|
+ fn(sender, e) {
|
|
|
+ if (e.ESC == e.getKey()) {
|
|
|
+ sender.onTriggerClick(sender);
|
|
|
+ } else {
|
|
|
+ const scope = sender.up("yvtree")
|
|
|
+ scope.filterByText(this.getRawValue());
|
|
|
+ }
|
|
|
+ },
|
|
|
+ buffer: 500
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ xtype: 'button', iconCls: 'x-fa fa-refresh', tooltip: '刷新',
|
|
|
+ listeners: {
|
|
|
+ click(sender) {
|
|
|
+ const scope = sender.up("yvtree")
|
|
|
+ scope.reload()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ xtype: 'button', iconCls: 'x-fa fa-plus-square-o', tooltip: '全部展开',
|
|
|
+ listeners: {
|
|
|
+ click(sender) {
|
|
|
+ const scope = sender.up("yvtree")
|
|
|
+ scope.expandAll()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ xtype: 'button', iconCls: 'x-fa fa-minus-square-o', tooltip: '全部收起',
|
|
|
+ listeners: {
|
|
|
+ click(sender) {
|
|
|
+ const scope = sender.up("yvtree")
|
|
|
+ scope.collapseAll()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function convertDataSource(sender, scope, newConfig) {
|
|
|
+ if (typeof newConfig.store !== 'undefined') {
|
|
|
+ // 有 store 属性的情况下,不做任何事
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (typeof newConfig.dataSource === 'undefined') {
|
|
|
+ // 没有定义 dataSource 的情况下,不做任何事
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let {dataSource} = newConfig
|
|
|
+ if (typeof dataSource === 'string') {
|
|
|
+ // dataSource 是字符串的情况下,找到成员函数
|
|
|
+ dataSource = lookupFn(scope, dataSource)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (typeof dataSource === 'function') {
|
|
|
+ // dataSource 是函数的情况下,在 afterrender 之后进行回调
|
|
|
+ newConfig.store = new Ext.data.TreeStore({
|
|
|
+ root: {
|
|
|
+ expanded: true,
|
|
|
+ children: []
|
|
|
+ }
|
|
|
+ })
|
|
|
+ newConfig.dataSourceCallbackFn = dataSource
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // throw new TypeError('无法识别的调用方法')
|
|
|
+}
|