From f79ef10e49eecfa94a8814286800b4b6ec204d82 Mon Sep 17 00:00:00 2001 From: liaoxuezhi Date: Mon, 21 Oct 2019 19:02:32 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=9F=E4=B8=80=20qs.stringify=20=E5=9B=A0?= =?UTF-8?q?=E4=B8=BA=E5=8F=AF=E8=83=BD=E4=BC=9A=E7=BB=9F=E4=B8=80=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Scoped.tsx | 4 +-- src/renderers/CRUD.tsx | 68 +++++++++++++++++-------------------- src/renderers/Form/File.tsx | 5 +-- src/store/crud.ts | 4 +-- src/utils/api.ts | 6 ++-- src/utils/helper.ts | 19 ++++++++--- 6 files changed, 57 insertions(+), 49 deletions(-) diff --git a/src/Scoped.tsx b/src/Scoped.tsx index bf1f40936..850fc5fb1 100644 --- a/src/Scoped.tsx +++ b/src/Scoped.tsx @@ -10,7 +10,7 @@ import hoistNonReactStatic = require('hoist-non-react-statics'); import qs from 'qs'; import {dataMapping} from './utils/tpl-builtin'; import {RendererEnv, RendererProps} from './factory'; -import {noop, autobind} from './utils/helper'; +import {noop, autobind, qsstringify} from './utils/helper'; import {RendererData, Action} from './types'; interface ScopedComponentType extends React.Component { @@ -139,7 +139,7 @@ function createScopedTools(path?: string, parent?: AlisIScopedContext, env?: Ren ...(location.search ? qs.parse(location.search.substring(1)) : {}), ...values }; - const link = location.pathname + '?' + qs.stringify(query); + const link = location.pathname + '?' + qsstringify(query); env.updateLocation(link); } }); diff --git a/src/renderers/CRUD.tsx b/src/renderers/CRUD.tsx index 4be2d1d77..8109f1b00 100644 --- a/src/renderers/CRUD.tsx +++ b/src/renderers/CRUD.tsx @@ -10,7 +10,8 @@ import { isObjectShallowModified, noop, isVisible, - getVariable + getVariable, + qsstringify } from '../utils/helper'; import {observer} from 'mobx-react'; import partition = require('lodash/partition'); @@ -167,12 +168,7 @@ export default class CRUD extends React.Component { this.mounted = true; if (syncLocation && location && (location.query || location.search)) { - store.updateQuery( - qs.parse(location.search.substring(1)), - undefined, - pageField, - perPageField - ); + store.updateQuery(qs.parse(location.search.substring(1)), undefined, pageField, perPageField); } else if (syncLocation && !location && window.location.search) { store.updateQuery( qs.parse(window.location.search.substring(1)) as object, @@ -413,7 +409,7 @@ export default class CRUD extends React.Component { search: boolean = true ) { const {store, syncLocation, env, pageField, perPageField} = this.props; - values = syncLocation ? qs.parse(qs.stringify(values)) : values; + values = syncLocation ? qs.parse(qsstringify(values)) : values; store.updateQuery( { @@ -577,35 +573,35 @@ export default class CRUD extends React.Component { ); this.lastQuery = store.query; const data = createObject(store.data, store.query); - isEffectiveApi(api, data) + isEffectiveApi(api, data) ? store - .fetchInitData(api, data, { - successMessage: messages && messages.fetchSuccess, - errorMessage: messages && messages.fetchFailed, - autoAppend: true, - forceReload, - loadDataOnce, - source, - silent, - pageField, - perPageField, - loadDataMode, - syncResponse2Query - }) - .then(value => { - interval && - this.mounted && - (!stopAutoRefreshWhen || - !( - (stopAutoRefreshWhenModalIsOpen && store.hasModalOpened) || - evalExpression(stopAutoRefreshWhen, data) - )) && - (this.timer = setTimeout( - silentPolling ? this.silentSearch : this.search, - Math.max(interval, 3000) - )); - return value; - }) + .fetchInitData(api, data, { + successMessage: messages && messages.fetchSuccess, + errorMessage: messages && messages.fetchFailed, + autoAppend: true, + forceReload, + loadDataOnce, + source, + silent, + pageField, + perPageField, + loadDataMode, + syncResponse2Query + }) + .then(value => { + interval && + this.mounted && + (!stopAutoRefreshWhen || + !( + (stopAutoRefreshWhenModalIsOpen && store.hasModalOpened) || + evalExpression(stopAutoRefreshWhen, data) + )) && + (this.timer = setTimeout( + silentPolling ? this.silentSearch : this.search, + Math.max(interval, 3000) + )); + return value; + }) : source && store.initFromScope(data, source); } diff --git a/src/renderers/Form/File.tsx b/src/renderers/Form/File.tsx index 58049e1ea..9fcb62bb1 100644 --- a/src/renderers/Form/File.tsx +++ b/src/renderers/Form/File.tsx @@ -9,6 +9,7 @@ import ImageControl from './Image'; import {Payload} from '../../types'; import {filter} from '../../utils/tpl'; import Alert from '../../components/Alert2'; +import {qsstringify} from '../../utils/helper'; export interface FileProps extends FormControlProps { btnClassName: string; @@ -493,9 +494,9 @@ export default class FileControl extends React.Component { ...qs.parse(reciever.substring(idx + 1)), ...params }; - reciever = reciever.substring(0, idx) + '?' + qs.stringify(params); + reciever = reciever.substring(0, idx) + '?' + qsstringify(params); } else if (params) { - reciever += '?' + qs.stringify(params); + reciever += '?' + qsstringify(params); } return this._send(reciever, fd, { diff --git a/src/store/crud.ts b/src/store/crud.ts index 45d5eb7f1..bc58f7814 100644 --- a/src/store/crud.ts +++ b/src/store/crud.ts @@ -1,7 +1,7 @@ import {types, getParent, flow, getEnv, getRoot} from 'mobx-state-tree'; import {IRendererStore} from './index'; import {ServiceStore} from './service'; -import {extendObject, createObject, isObjectShallowModified, sortArray, isEmpty} from '../utils/helper'; +import {extendObject, createObject, isObjectShallowModified, sortArray, isEmpty, qsstringify} from '../utils/helper'; import {Api, Payload, fetchOptions, Action} from '../types'; import qs from 'qs'; import pick = require('lodash/pick'); @@ -91,7 +91,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore') updater && isObjectShallowModified(originQuery, self.query, false) && - setTimeout(() => updater(`?${qs.stringify(self.query, {encodeValuesOnly: true})}`), 4); + setTimeout(() => updater(`?${qsstringify(self.query)}`), 4); } const fetchInitData: ( diff --git a/src/utils/api.ts b/src/utils/api.ts index 80238fe34..86828448b 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -3,7 +3,7 @@ import {fetcherConfig} from '../factory'; import {tokenize, dataMapping} from './tpl-builtin'; import qs from 'qs'; import {evalExpression} from './tpl'; -import {isObject, isObjectShallowModified, hasFile, object2formData} from './helper'; +import {isObject, isObjectShallowModified, hasFile, object2formData, qsstringify} from './helper'; const rSchema = /(?:^|raw\:)(get|post|put|delete|patch|options|head):/i; @@ -81,9 +81,9 @@ export function buildApi( ...qs.parse(api.url.substring(idx + 1)), ...api.data }; - api.url = api.url.substring(0, idx) + '?' + qs.stringify(params); + api.url = api.url.substring(0, idx) + '?' + qsstringify(params); } else { - api.url += '?' + qs.stringify(api.data); + api.url += '?' + qsstringify(api.data); } delete api.data; } diff --git a/src/utils/helper.ts b/src/utils/helper.ts index 6fc54f5bf..17d113b85 100644 --- a/src/utils/helper.ts +++ b/src/utils/helper.ts @@ -777,14 +777,25 @@ export function hasFile(object: any): boolean { }); } +export function qsstringify( + data: any, + options: any = { + arrayFormat: 'brackets', + encodeValuesOnly: true + } +) { + return qs.stringify(data, options); +} + export function object2formData( data: any, options: any = { - arrayForamt: 'brackets' - } + arrayFormat: 'brackets', + encodeValuesOnly: true + }, + fd: FormData = new FormData() ): any { let others: any = {}; - const fd = new FormData(); Object.keys(data).forEach(key => { const value = data[key]; @@ -798,7 +809,7 @@ export function object2formData( }); // 因为 key 的格式太多了,偷个懒,用 qs 来处理吧。 - qs.stringify(others, options) + qsstringify(others, options) .split('&') .forEach(item => { let parts = item.split('=');