From 4ddbfe6a1b4ba93c2486289ba409407cfa79506d Mon Sep 17 00:00:00 2001 From: Alan Wei Date: Fri, 4 May 2018 17:45:38 +0800 Subject: [PATCH] refactor getFlatMenuKeys & getMeunMatchKeys to improve code readability & robustness --- src/components/SiderMenu/SiderMenu.js | 55 +++++++++++---------- src/components/SiderMenu/SilderMenu.test.js | 41 ++++++++++++--- 2 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/components/SiderMenu/SiderMenu.js b/src/components/SiderMenu/SiderMenu.js index 188d79eb..9b7300f9 100644 --- a/src/components/SiderMenu/SiderMenu.js +++ b/src/components/SiderMenu/SiderMenu.js @@ -22,17 +22,37 @@ const getIcon = icon => { return icon; }; -export const getMeunMatchKeys = (flatMenuKeys, path) => { - return flatMenuKeys.filter(item => { - return pathToRegexp(item).test(path); - }); -}; +/** + * Recursively flatten the data + * [{path:string},{path:string}] => {path,path2} + * @param menu + */ +export const getFlatMenuKeys = menu => + menu.reduce((keys, item) => { + keys.push(item.path); + if (item.children) { + return keys.concat(getFlatMenuKeys(item.children)); + } + return keys; + }, []); + +/** + * Find all matched menu keys based on paths + * @param flatMenuKeys: [/abc, /abc/:id, /abc/:id/info] + * @param paths: [/abc, /abc/11, /abc/11/info] + */ +export const getMeunMatchKeys = (flatMenuKeys, paths) => + paths.reduce( + (matchKeys, path) => + matchKeys.concat(flatMenuKeys.filter(item => pathToRegexp(item).test(path))), + [] + ); export default class SiderMenu extends PureComponent { constructor(props) { super(props); this.menus = props.menuData; - this.flatMenuKeys = this.getFlatMenuKeys(props.menuData); + this.flatMenuKeys = getFlatMenuKeys(props.menuData); this.state = { openKeys: this.getDefaultCollapsedSubMenus(props), }; @@ -51,26 +71,7 @@ export default class SiderMenu extends PureComponent { */ getDefaultCollapsedSubMenus(props) { const { location: { pathname } } = props || this.props; - return urlToList(pathname) - .map(item => { - return getMeunMatchKeys(this.flatMenuKeys, item)[0]; - }) - .filter(item => item); - } - /** - * Recursively flatten the data - * [{path:string},{path:string}] => {path,path2} - * @param menus - */ - getFlatMenuKeys(menus) { - let keys = []; - menus.forEach(item => { - if (item.children) { - keys = keys.concat(this.getFlatMenuKeys(item.children)); - } - keys.push(item.path); - }); - return keys; + return getMeunMatchKeys(this.flatMenuKeys, urlToList(pathname)); } /** * 判断是否是http链接.返回 Link 或 a @@ -159,7 +160,7 @@ export default class SiderMenu extends PureComponent { // Get the currently selected menu getSelectedMenuKeys = () => { const { location: { pathname } } = this.props; - return urlToList(pathname).map(itemPath => getMeunMatchKeys(this.flatMenuKeys, itemPath).pop()); + return getMeunMatchKeys(this.flatMenuKeys, urlToList(pathname)); }; // conversion Path // 转化路径 diff --git a/src/components/SiderMenu/SilderMenu.test.js b/src/components/SiderMenu/SilderMenu.test.js index 9b181c8c..fd99093b 100644 --- a/src/components/SiderMenu/SilderMenu.test.js +++ b/src/components/SiderMenu/SilderMenu.test.js @@ -1,24 +1,49 @@ -import { getMeunMatchKeys } from './SiderMenu'; +import { urlToList } from '../_utils/pathTools'; +import { getFlatMenuKeys, getMeunMatchKeys } from './SiderMenu'; -const meun = ['/dashboard', '/userinfo', '/dashboard/name', '/userinfo/:id', '/userinfo/:id/info']; +const menu = [{ + path: '/dashboard', + children: [{ + path: '/dashboard/name', + }], +}, { + path: '/userinfo', + children: [{ + path: '/userinfo/:id', + children: [{ + path: '/userinfo/:id/info', + }], + }], +}]; -describe('test meun match', () => { +const flatMenuKeys = getFlatMenuKeys(menu); + +describe('test convert tree structure menu paths to flat menu paths', () => { + it('simple menu', () => { + expect(flatMenuKeys).toEqual( + ['/dashboard', '/dashboard/name', '/userinfo', '/userinfo/:id', '/userinfo/:id/info'] + ); + }) +}); + +describe('test menu match', () => { it('simple path', () => { - expect(getMeunMatchKeys(meun, '/dashboard')).toEqual(['/dashboard']); + expect(getMeunMatchKeys(flatMenuKeys, urlToList('/dashboard'), true)).toEqual(['/dashboard']); }); + it('error path', () => { - expect(getMeunMatchKeys(meun, '/dashboardname')).toEqual([]); + expect(getMeunMatchKeys(flatMenuKeys, urlToList('/dashboardname'), true)).toEqual([]); }); it('Secondary path', () => { - expect(getMeunMatchKeys(meun, '/dashboard/name')).toEqual(['/dashboard/name']); + expect(getMeunMatchKeys(flatMenuKeys, urlToList('/dashboard/name'), true)).toEqual(['/dashboard', '/dashboard/name']); }); it('Parameter path', () => { - expect(getMeunMatchKeys(meun, '/userinfo/2144')).toEqual(['/userinfo/:id']); + expect(getMeunMatchKeys(flatMenuKeys, urlToList('/userinfo/2144'), true)).toEqual(['/userinfo', '/userinfo/:id']); }); it('three parameter path', () => { - expect(getMeunMatchKeys(meun, '/userinfo/2144/info')).toEqual(['/userinfo/:id/info']); + expect(getMeunMatchKeys(flatMenuKeys, urlToList('/userinfo/2144/info'), false)).toEqual(['/userinfo', '/userinfo/:id', '/userinfo/:id/info']); }); }); -- GitLab