From 44ba2514a5564b690cc6ff95a2b37b2d482242b0 Mon Sep 17 00:00:00 2001 From: cipchk Date: Sun, 6 May 2018 23:57:14 +0800 Subject: [PATCH] refactor(all): used deep-extend replace deep copy, close #412 --- .prettierignore | 2 - build.sh | 18 ++-- docs/style-guide.md | 2 + package.json | 20 ++-- packages/abc/image/image.directive.ts | 2 +- packages/abc/package.json | 3 +- packages/abc/rollup.config.js | 3 + packages/abc/sidebar-nav/sidebar-nav.spec.ts | 8 +- .../simple-table/simple-table.component.ts | 22 ++-- .../abc/simple-table/simple-table.spec.ts | 7 +- packages/abc/utils/utils.spec.ts | 4 +- packages/abc/utils/utils.ts | 7 +- packages/form/package.json | 3 +- packages/form/rollup.config.js | 6 +- packages/form/spec/form.spec.ts | 4 +- packages/form/spec/schema.spec.ts | 10 +- packages/form/src/sf-fixed.directive.ts | 4 +- packages/form/src/sf.component.ts | 29 ++--- packages/form/src/utils.ts | 9 +- packages/theme/package.json | 3 +- packages/theme/services/http/http.spec.ts | 2 +- .../theme/services/menu/menu.service.spec.ts | 20 ++-- .../routes/theme/editor/editor.component.ts | 2 +- src/app/routes/demo/demo.component.ts | 101 ++++++++++-------- tslint.json | 6 ++ 25 files changed, 167 insertions(+), 130 deletions(-) diff --git a/.prettierignore b/.prettierignore index d87a3799db..e69de29bb2 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +0,0 @@ -/src -/site diff --git a/build.sh b/build.sh index 139cc886fe..5ea151a27c 100644 --- a/build.sh +++ b/build.sh @@ -5,15 +5,15 @@ set -u -e -o pipefail readonly currentDir=$(cd $(dirname $0); pwd) cd ${currentDir} -PACKAGES=(cli) -# PACKAGES=(acl -# theme -# abc -# auth -# cache -# mock -# form -# cli) +# PACKAGES=(form) +PACKAGES=(acl + theme + abc + auth + cache + mock + form + cli) NODE_PACKAGES=(cli) ####################################### diff --git a/docs/style-guide.md b/docs/style-guide.md index 2076d291ab..c64d2deb02 100644 --- a/docs/style-guide.md +++ b/docs/style-guide.md @@ -91,3 +91,5 @@ ng-alain 使用 [Prettier](https://prettier.io/) 来优化代码风格,并且 `lint` 可以非常有效的帮助我们更早发现bug、更高的可读性;如果我们能够保证团队开发过程中每一次 commit 前都自动做一次 staged 中文件的 lint 的话,那不是非常酷吗? ng-alain 配置了每次对 staged 进行 commit 时会预先做 lint,若发现错误则无法提交。 + +默认开启了 `*.ts`、`*.less` 的提交过程中强制对代码进行格式化,你可以通过修改 `package.json` 的 `lint-staged` 节点来改变些规则(例如:`prettier --write`)。 diff --git a/package.json b/package.json index c3399907c4..f924218433 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ "precommit": "npm run lint-staged", "analyze": "ng build --prod --build-optimizer --stats-json", "prepush": "npm run lint", - "lint": "run-s lint:ts lint:style", - "lint:ts": "tslint -p tsconfig.json -c tslint.json 'packages/**/*.ts' -e 'packages/**/*.spec.ts' -e 'packages/cli/**/*'", + "lint": "npm run lint:ts && npm run lint:style", + "lint:ts": "tslint -p tsconfig.json -c tslint.json 'packages/**/*.ts'", "lint:style": "stylelint \"{packages}/**/*.less\" --syntax less", "tslint-check": "tslint-config-prettier-check ./tslint.json", "lint-staged": "lint-staged", @@ -57,6 +57,7 @@ "@antv/g2-plugin-slider": "^2.0.0", "@ngx-translate/core": "^9.0.1", "@stackblitz/sdk": "^1.1.1", + "deep-extend": "^0.5.1", "file-saver": "^1.3.3", "marked": "^0.3.9", "ng-zorro-antd": "^0.7.0-beta.5", @@ -73,6 +74,7 @@ "@angular/compiler-cli": "^5.0.0", "@angular/language-service": "^5.0.0", "@schematics/schematics": "^0.4.6", + "@types/deep-extend": "^0.4.31", "@types/fs-extra": "^5.0.1", "@types/gulp": "^4.0.4", "@types/htmlparser2": "^3.7.31", @@ -85,15 +87,15 @@ "chalk": "^2.3.0", "codecov": "^3.0.0", "codelyzer": "~4.2.1", - "editorconfig-tools": "^0.1.1", - "husky": "^0.14.3", "del": "^3.0.0", "docsearch.js": "^2.5.2", "domhandler": "^2.4.1", + "editorconfig-tools": "^0.1.1", "enquire.js": "^2.1.6", "fs-extra": "^5.0.0", "gh-pages": "^1.1.0", "htmlparser2": "^3.9.2", + "husky": "^0.14.3", "jasmine-core": "~2.8.0", "jasmine-spec-reporter": "~4.2.1", "jsonml.js": "^0.1.0", @@ -103,30 +105,30 @@ "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "klaw-sync": "^3.0.2", + "lint-staged": "^7.0.5", "mark-twain": "^2.0.2", "mkdirp": "^0.5.1", - "lint-staged": "^7.0.5", "mockjs": "^1.0.1-beta3", "mustache": "^2.3.0", "ng-github-button": "^0.0.1", "ng2-ace-editor": "^0.3.7", "ngx-tinymce": "^1.0.1", "ngx-ueditor": "^1.1.0", + "prettier": "^1.12.1", + "prettier-stylelint": "^0.4.2", "protractor": "~5.2.2", "rollup": "^0.49.2", "rollup-plugin-node-resolve": "^3.0.0", "rollup-plugin-replace": "^2.0.0", "rollup-plugin-sourcemaps": "^0.4.2", "rollup-plugin-uglify": "^2.0.1", - "prettier": "^1.12.1", - "prettier-stylelint": "^0.4.2", "stylelint": "^8.2.0", "stylelint-config-standard": "^18.0.0", "through2": "^2.0.3", "ts-node": "~4.1.0", "tslint": "~5.8.0", - "tslint-language-service": "^0.9.6", "tslint-config-prettier": "^1.12.0", + "tslint-language-service": "^0.9.6", "typescript": "~2.6.0", "webpack-bundle-analyzer": "^2.9.2", "xlsx": "^0.11.16" @@ -138,12 +140,10 @@ ], "packages/**/*.ts": [ "npm run lint:ts", - "prettier --write", "git add" ], "packages/**/*.less": [ "npm run lint:style", - "prettier --write", "git add" ] } diff --git a/packages/abc/image/image.directive.ts b/packages/abc/image/image.directive.ts index 45ab4d5e74..00fcf95376 100644 --- a/packages/abc/image/image.directive.ts +++ b/packages/abc/image/image.directive.ts @@ -32,7 +32,7 @@ export class ImageDirective implements OnChanges, OnInit { private render: Renderer2, DEF: AdImageConfig, ) { - Object.assign(this, deepCopy(DEF)); + Object.assign(this, deepCopy({}, DEF)); } ngOnInit(): void { diff --git a/packages/abc/package.json b/packages/abc/package.json index 8e4fbf6453..657fabc9ca 100644 --- a/packages/abc/package.json +++ b/packages/abc/package.json @@ -20,6 +20,7 @@ "@delon/theme": "PEER-0.0.0-PLACEHOLDER", "@delon/acl": "PEER-0.0.0-PLACEHOLDER", "file-saver": "^1.3.3", - "ngx-countdown": "^2.1.0" + "ngx-countdown": "^2.1.0", + "deep-extend": "^0.5.1" } } diff --git a/packages/abc/rollup.config.js b/packages/abc/rollup.config.js index c18968543c..021e812974 100644 --- a/packages/abc/rollup.config.js +++ b/packages/abc/rollup.config.js @@ -51,6 +51,8 @@ const globals = { 'date-fns/sub_years': 'date-fns/sub_years/index', 'date-fns/add_days': 'date-fns/add_days/index', + 'deep-extend': 'deep-extend', + '@delon/theme': 'alain.theme', '@delon/acl': 'alain.acl', }; @@ -70,6 +72,7 @@ const listOfDateFns = [ 'endOfYear', 'subYears', 'addDays', + 'deepExtend', ]; const listOfReplace = listOfDateFns.map(name => { diff --git a/packages/abc/sidebar-nav/sidebar-nav.spec.ts b/packages/abc/sidebar-nav/sidebar-nav.spec.ts index 806c69c139..a29eca5146 100644 --- a/packages/abc/sidebar-nav/sidebar-nav.spec.ts +++ b/packages/abc/sidebar-nav/sidebar-nav.spec.ts @@ -70,7 +70,7 @@ describe('abc: sidebar-nav', () => { router = injector.get(Router); setSrv = injector.get(SettingsService); menuSrv = injector.get(MenuService); - menuSrv.add(deepCopy(MOCKMENUS)); + menuSrv.add(deepCopy([], MOCKMENUS)); page = new PageObject(); if (needMockNavigateByUrl) spyOn(router, 'navigateByUrl'); if (callback) callback(); @@ -96,7 +96,7 @@ describe('abc: sidebar-nav', () => { it('should be navigate url', () => { createComp(); spyOn(context, 'select'); - const data = deepCopy(MOCKMENUS); + const data = deepCopy([], MOCKMENUS); menuSrv.add(data); expect(context.select).not.toHaveBeenCalled(); expect(router.navigateByUrl).not.toHaveBeenCalled(); @@ -109,7 +109,7 @@ describe('abc: sidebar-nav', () => { it('should be toggle open', () => { createComp(); - const data = deepCopy(MOCKMENUS); + const data = deepCopy([], MOCKMENUS); menuSrv.add(data); expect(data[0].children[0]._open).toBeUndefined(); const subTitleEl = getEl('.nav-sub-title'); @@ -121,7 +121,7 @@ describe('abc: sidebar-nav', () => { it('should be reset menu when service is changed', () => { createComp(); isText('.nav-group-title', MOCKMENUS[0].text); - const newMenu = deepCopy(MOCKMENUS); + const newMenu = deepCopy([], MOCKMENUS); newMenu[0].text = 'new主导航'; menuSrv.add(newMenu); fixture.detectChanges(); diff --git a/packages/abc/simple-table/simple-table.component.ts b/packages/abc/simple-table/simple-table.component.ts index 68080b623b..6d2ea35998 100644 --- a/packages/abc/simple-table/simple-table.component.ts +++ b/packages/abc/simple-table/simple-table.component.ts @@ -14,7 +14,6 @@ import { SimpleChange, QueryList, ViewChildren, - AfterViewInit, ContentChildren, ContentChild, Optional, @@ -65,8 +64,9 @@ import { SimpleTableExport } from './simple-table-export'; preserveWhitespaces: false, }) export class SimpleTableComponent - implements OnInit, OnChanges, AfterViewInit, OnDestroy { + implements OnInit, OnChanges, OnDestroy { private data$: Subscription; + private _inited = false; _data: SimpleTableData[] = []; _url: string; _isAjax = false; @@ -333,7 +333,7 @@ export class SimpleTableComponent private number: DecimalPipe, @Inject(DOCUMENT) private doc: any, ) { - Object.assign(this, deepCopy(defConfig)); + Object.assign(this, deepCopy({}, defConfig)); } // region: data @@ -399,6 +399,7 @@ export class SimpleTableComponent } _change(type: 'pi' | 'ps') { + if (!this._inited) return ; this._genAjax(); this._genData(); this._toTop(); @@ -842,9 +843,11 @@ export class SimpleTableComponent // endregion - ngOnInit(): void {} - - ngAfterViewInit(): void {} + ngOnInit(): void { + this._inited = true; + this.updateColumns(); + this.processData(); + } private setClass() { this._classMap.forEach(cls => @@ -869,7 +872,8 @@ export class SimpleTableComponent const sortMap: Object = {}; let idx = 0; const newColumns: SimpleTableColumn[] = []; - for (const item of this.columns) { + const copyColumens = deepCopy([], this.columns); + for (const item of copyColumens) { if (this.acl && item.acl && !this.acl.can(item.acl)) continue; if (item.index) { if (!Array.isArray(item.index)) item.index = item.index.split('.'); @@ -977,8 +981,8 @@ export class SimpleTableComponent ngOnChanges( changes: { [P in keyof this]?: SimpleChange } & SimpleChanges, ): void { - if (changes.columns) this.updateColumns(); - if (changes.data) this.processData(); + if (changes.columns && this._inited) this.updateColumns(); + if (changes.data && this._inited) this.processData(); this.setClass(); } diff --git a/packages/abc/simple-table/simple-table.spec.ts b/packages/abc/simple-table/simple-table.spec.ts index 1fc021ccde..30dce0804b 100644 --- a/packages/abc/simple-table/simple-table.spec.ts +++ b/packages/abc/simple-table/simple-table.spec.ts @@ -26,6 +26,7 @@ import { } from './interface'; import { AdSimpleTableModule } from './simple-table.module'; import { SimpleTableComponent } from './simple-table.component'; +import { deepCopy } from '..'; const USERS: any[] = Array(100) .fill({}) @@ -256,7 +257,7 @@ describe('abc: simple-table', () => { describe('static data', () => { it('should be not pagination when data length less than ps value', () => { genModule({ - template: ``, + template: ``, }); context.data = USERS.slice(0, 3); context.ps = 4; @@ -379,7 +380,7 @@ describe('abc: simple-table', () => { }) class TestComponent { @ViewChild('st') comp: SimpleTableComponent; - data: string | any[] = JSON.parse(JSON.stringify(USERS)); + data: string | any[] = deepCopy([], USERS); extraParams: any; reqMehtod: string; reqBody: any; @@ -388,7 +389,7 @@ class TestComponent { reqError() {} resReName: ResReNameType; ps = PS; - columns: SimpleTableColumn[] = JSON.parse(JSON.stringify(COLUMNS)); + columns: SimpleTableColumn[] = deepCopy([], COLUMNS); pi: number; total: number; showPagination = true; diff --git a/packages/abc/utils/utils.spec.ts b/packages/abc/utils/utils.spec.ts index 9c37981849..dabc997024 100644 --- a/packages/abc/utils/utils.spec.ts +++ b/packages/abc/utils/utils.spec.ts @@ -158,8 +158,8 @@ describe('abc: utils', () => { }); it('#deepCopy', () => { - const a = 1; - expect(deepCopy(a)).toBe(a); + const a = { number: 1 }; + expect(deepCopy({}, a).number).toBe(a.number); }); describe('#copy', () => { diff --git a/packages/abc/utils/utils.ts b/packages/abc/utils/utils.ts index 5dc72ad2f3..30943a435c 100644 --- a/packages/abc/utils/utils.ts +++ b/packages/abc/utils/utils.ts @@ -9,6 +9,7 @@ import * as startOfYear from 'date-fns/start_of_year'; import * as endOfYear from 'date-fns/end_of_year'; import * as subYears from 'date-fns/sub_years'; import * as addDays from 'date-fns/add_days'; +import * as deepExtend from 'deep-extend'; /** * 转化成RMB元字符串 @@ -87,9 +88,9 @@ export function deepGet(obj: any, path: string[], defaultValue?: any) { return path.reduce((o, k) => o[k], obj) || defaultValue; } -export function deepCopy(obj: any) { - // BAD: a temporary solution - return JSON.parse(JSON.stringify(obj)); +export function deepCopy(target: any, obj: any) { + const result = deepExtend({ }, { __source: obj }); + return result.__source; } /** 复制内容至剪贴板 */ diff --git a/packages/form/package.json b/packages/form/package.json index 6dae29a26d..678c220641 100644 --- a/packages/form/package.json +++ b/packages/form/package.json @@ -30,6 +30,7 @@ "ng-zorro-antd" ], "peerDependencies": { - "ng-zorro-antd": "ZORRO-0.0.0-PLACEHOLDER" + "ng-zorro-antd": "ZORRO-0.0.0-PLACEHOLDER", + "deep-extend": "^0.5.1" } } diff --git a/packages/form/rollup.config.js b/packages/form/rollup.config.js index 8d278fd908..2b14cd09bd 100644 --- a/packages/form/rollup.config.js +++ b/packages/form/rollup.config.js @@ -31,9 +31,13 @@ const globals = { 'rxjs/observable/combineLatest': 'Rx.Observable', 'date-fns/format': 'date-fns/format/index', + 'deep-extend': 'deep-extend', }; -const listOfDateFns = ['format']; +const listOfDateFns = [ + 'format', + 'deepExtend' +]; const listOfReplace = listOfDateFns.map(name => { const map = {}; diff --git a/packages/form/spec/form.spec.ts b/packages/form/spec/form.spec.ts index 7764660049..257df45295 100644 --- a/packages/form/spec/form.spec.ts +++ b/packages/form/spec/form.spec.ts @@ -1,6 +1,6 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture } from '@angular/core/testing'; -import { deepCopy } from '@delon/abc'; +import * as deepExtend from 'deep-extend'; import { builder, TestFormComponent, SFPage, SCHEMA } from './base.spec'; import { SFSchema } from '../src/schema/index'; import { SFUISchemaItem, SFUISchema } from '../src/schema/ui'; @@ -138,7 +138,7 @@ describe('form: component', () => { describe('#reset', () => { it('should be set default value', () => { - const schema = deepCopy(SCHEMA.user) as SFSchema; + const schema = deepExtend({}, SCHEMA.user) as SFSchema; schema.properties.name.default = 'cipchk'; page .newSchema(schema) diff --git a/packages/form/spec/schema.spec.ts b/packages/form/spec/schema.spec.ts index 42662da148..de3ad5b335 100644 --- a/packages/form/spec/schema.spec.ts +++ b/packages/form/spec/schema.spec.ts @@ -1,6 +1,6 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture } from '@angular/core/testing'; -import { deepCopy } from '@delon/abc'; +import * as deepExtend from 'deep-extend'; import { builder, TestFormComponent, SFPage, SCHEMA } from './base.spec'; import { SFSchema } from '../src/schema/index'; import { SFUISchemaItem, SFUISchema } from '../src/schema/ui'; @@ -149,8 +149,8 @@ describe('form: schema', () => { }; describe('[#via in json schema]', () => { it('should be has $items when is array', () => { - const schema = deepCopy(arrSchema) as SFSchema; - schema.properties.name.ui = deepCopy(arrUI); + const schema = deepExtend({}, arrSchema) as SFSchema; + schema.properties.name.ui = deepExtend({}, arrUI); page .newSchema(schema) .checkUI('/name', 'grid.arraySpan', arrUI.grid.arraySpan); @@ -158,11 +158,11 @@ describe('form: schema', () => { }); describe('[#via ui property]', () => { it('should be has $items when is array', () => { - const schema = deepCopy(arrSchema); + const schema = deepExtend({}, arrSchema); const uiSchema: SFUISchema = { $name: { $items: {}, - ...deepCopy(arrUI), + ...deepExtend({}, arrUI), }, }; page diff --git a/packages/form/src/sf-fixed.directive.ts b/packages/form/src/sf-fixed.directive.ts index 3c7a51acb2..2a84ad4bbc 100644 --- a/packages/form/src/sf-fixed.directive.ts +++ b/packages/form/src/sf-fixed.directive.ts @@ -16,7 +16,7 @@ export class SFFixedDirective implements AfterViewInit, OnChanges { @Input('fixed-label') num: number; private init() { - if (this._inited || this.num == null || this.num <= 0) return; + if (!this._inited || this.num == null || this.num <= 0) return; const widgetEl = this.el.querySelector('.ant-row') || this.el; this.render.addClass(widgetEl, 'sf-fixed'); const labelEl = widgetEl.querySelector('.ant-form-item-label'); @@ -30,7 +30,6 @@ export class SFFixedDirective implements AfterViewInit, OnChanges { ); this.render.setStyle(controlEl, 'margin-left', unit); } - this._inited = true; } constructor(er: ElementRef, private render: Renderer2) { @@ -38,6 +37,7 @@ export class SFFixedDirective implements AfterViewInit, OnChanges { } ngAfterViewInit(): void { + this._inited = true; this.init(); } diff --git a/packages/form/src/sf.component.ts b/packages/form/src/sf.component.ts index 27bc4a453d..bfed17ea2f 100644 --- a/packages/form/src/sf.component.ts +++ b/packages/form/src/sf.component.ts @@ -13,6 +13,7 @@ import { ChangeDetectorRef, } from '@angular/core'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; +import * as deepExtend from 'deep-extend'; import { DelonFormConfig } from './config'; import { di, retrieveSchema, FORMATMAPS, resolveIf } from './utils'; import { TerminatorService } from './terminator.service'; @@ -79,11 +80,12 @@ export class SFComponent implements OnInit, OnChanges, OnDestroy { rootProperty: FormProperty = null; _formData: any; _btn: SFButton; + _schema: SFSchema; _ui: SFUISchema; private _item: any; private _valid = true; private _defUi: SFUISchemaItem; - private inited = false; + private _inited = false; // region: fields @@ -203,7 +205,8 @@ export class SFComponent implements OnInit, OnChanges, OnDestroy { private coverProperty() { const isHorizontal = this.layout === 'horizontal'; - const { definitions } = this.schema; + const _schema = deepExtend({}, this.schema); + const { definitions } = _schema; const inFn = ( schema: SFSchema, @@ -301,20 +304,22 @@ export class SFComponent implements OnInit, OnChanges, OnDestroy { liveValidate: this.liveValidate, firstVisual: this.firstVisual, }, - this.schema.ui, + _schema.ui, this.ui['*'], ); // root this._ui = Object.assign({}, this._defUi); - inFn(this.schema, this.schema, this.ui, this.ui, this._ui); + inFn(_schema, _schema, this.ui, this.ui, this._ui); // cond - resolveIf(this.schema, this._ui); - inIfFn(this.schema, this._ui); + resolveIf(_schema, this._ui); + inIfFn(_schema, this._ui); - if (this._ui.debug) di('cover schema & ui', this._ui, this.schema); + this._schema = _schema; + + if (this._ui.debug) di('cover schema & ui', this._ui, _schema); } private coverButtonProperty() { @@ -347,7 +352,7 @@ export class SFComponent implements OnInit, OnChanges, OnDestroy { } ngOnInit(): void { - this.inited = true; + this._inited = true; this.validator(); } @@ -391,17 +396,13 @@ export class SFComponent implements OnInit, OnChanges, OnDestroy { this._formData = { ...this.formData }; - if (this.inited) this.terminator.destroy(); + if (this._inited) this.terminator.destroy(); this.coverProperty(); this.coverButtonProperty(); - if (this._ui.debug) { - di('schema', this.schema); - } - this.rootProperty = this.formPropertyFactory.createProperty( - this.schema, + this._schema, this._ui, this.formData, ); diff --git a/packages/form/src/utils.ts b/packages/form/src/utils.ts index c642a8fd7e..50da6664af 100644 --- a/packages/form/src/utils.ts +++ b/packages/form/src/utils.ts @@ -1,6 +1,7 @@ import { Observable } from 'rxjs/Observable'; import { map, takeWhile } from 'rxjs/operators'; import { of } from 'rxjs/observable/of'; +import * as deepExtend from 'deep-extend'; import { SFUISchema, SFUISchemaItem, SFUISchemaItemRun } from './schema/ui'; import { SFSchema, SFSchemaDefinition, SFSchemaEnum } from './schema'; @@ -26,11 +27,6 @@ export function di(...args) { console.warn(...args); } -export function deepCopy(obj: any) { - // BAD: a temporary solution - return JSON.parse(JSON.stringify(obj)); -} - export function deepGet(obj: any, path: string[], defaultValue?: any) { if (!obj || path == null || path.length === 0) return defaultValue; if (path.length === 1) { @@ -191,7 +187,8 @@ export function getEnum(list: any[], formData: any): SFSchemaEnum[] { } export function getCopyEnum(list: any[], formData: any) { - return getEnum(deepCopy(list || []), formData); + const copy = deepExtend({ }, { __source: list || [] }).__source; + return getEnum(copy, formData); } export function getData( diff --git a/packages/theme/package.json b/packages/theme/package.json index c1b86606d0..a2a9072a4e 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -18,6 +18,7 @@ "keywords": ["delon", "ng-alain", "alain", "antd", "ng-zorro-antd"], "peerDependencies": { "ng-zorro-antd": "ZORRO-0.0.0-PLACEHOLDER", - "@delon/acl": "PEER-0.0.0-PLACEHOLDER" + "@delon/acl": "PEER-0.0.0-PLACEHOLDER", + "deep-extend": "^0.5.1" } } diff --git a/packages/theme/services/http/http.spec.ts b/packages/theme/services/http/http.spec.ts index b1dfa6e783..e3d5c9fd50 100644 --- a/packages/theme/services/http/http.spec.ts +++ b/packages/theme/services/http/http.spec.ts @@ -74,7 +74,7 @@ describe('theme: http.client', () => { ret.flush(OK); }); it(`should be unix timestamp when is date param`, (done: () => void) => { - const p = Object.assign(deepCopy(PARAMS), { time, date: new Date() }); + const p = Object.assign(deepCopy({}, PARAMS), { time, date: new Date() }); http.get(URL, p).subscribe(res => { expect(res).toBe(OK); done(); diff --git a/packages/theme/services/menu/menu.service.spec.ts b/packages/theme/services/menu/menu.service.spec.ts index 37fa395958..fdaa269639 100644 --- a/packages/theme/services/menu/menu.service.spec.ts +++ b/packages/theme/services/menu/menu.service.spec.ts @@ -66,19 +66,19 @@ describe('Service: Menu', () => { }); it('#add', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); expect(srv.menus.length).toBe(DATA.length); }); it('#resume', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); let tick = 0; srv.resume(item => ++tick); expect(tick).toBeGreaterThan(0); }); it('#clear', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); expect(srv.menus.length).toBe(DATA.length); srv.clear(); expect(srv.menus.length).toBe(0); @@ -93,19 +93,19 @@ describe('Service: Menu', () => { describe('#openedByUrl', () => { it('with url', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); srv.openedByUrl(`/dashboard/v1`); expect(srv.menus[0]._open).toBe(true); }); it('not found', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); srv.openedByUrl(`/notfound`); expect(srv.menus.filter(w => w._open === false).length).toBe( srv.menus.length, ); }); it('invalid url', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); srv.openedByUrl(null); expect(srv.menus.filter(w => w._open === false).length).toBe(0); }); @@ -113,13 +113,13 @@ describe('Service: Menu', () => { describe('#getPathByUrl', () => { it('with url', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); const menus = srv.getPathByUrl(`/dashboard/v1`); expect(menus.length).toBe(2); expect(menus[0].text).toBe('dashboard'); }); it('invalid url', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); const menus = srv.getPathByUrl(`/dashboard/v1111`); expect(menus.length).toBe(0); }); @@ -127,7 +127,7 @@ describe('Service: Menu', () => { describe('#shortcuts', () => { it('should be under the dashboard', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); expect(srv.menus[0].children[1].children.length).toBe(1); }); it('should be use [shortcut_root: true]', () => { @@ -188,7 +188,7 @@ describe('Service: Menu', () => { describe('ISSUES', () => { it('ng-alain #107', () => { - srv.add(deepCopy(DATA)); + srv.add(deepCopy([], DATA)); expect( srv.menus[0].children.filter(w => w.shortcut_root === true).length, ).toBe(1); diff --git a/site/app/routes/theme/editor/editor.component.ts b/site/app/routes/theme/editor/editor.component.ts index 33209849cf..daf5ba9c37 100644 --- a/site/app/routes/theme/editor/editor.component.ts +++ b/site/app/routes/theme/editor/editor.component.ts @@ -86,7 +86,7 @@ export class ThemeEditorComponent { reset(nowData?: Object) { nowData = nowData || {}; - const data = deepCopy(DEFAULT); + const data = deepCopy({}, DEFAULT); Object.keys(data).forEach(key => { data[key] = Object.assign({}, data[key], { value: nowData[key] || data[key].default, diff --git a/src/app/routes/demo/demo.component.ts b/src/app/routes/demo/demo.component.ts index dd6549bc23..f330260ac1 100644 --- a/src/app/routes/demo/demo.component.ts +++ b/src/app/routes/demo/demo.component.ts @@ -1,16 +1,25 @@ -// tslint:disable:quotemark import { Component } from '@angular/core'; -import { SFSchema, SFSchemaEnum, CascaderWidget, SFUISchema, FormProperty, PropertyGroup } from '@delon/form'; -import { NzMessageService, CascaderOption, MentionOnSearchTypes } from 'ng-zorro-antd'; +import { + SFSchema, + SFSchemaEnum, + CascaderWidget, + SFUISchema, + FormProperty, + PropertyGroup, +} from '@delon/form'; +import { + NzMessageService, + CascaderOption, + MentionOnSearchTypes, +} from 'ng-zorro-antd'; import { of } from 'rxjs/observable/of'; import { delay, map, debounceTime, distinctUntilChanged } from 'rxjs/operators'; import { _HttpClient } from '@delon/theme'; @Component({ - selector: 'app-demo', - template: ` - layout="inline" - layout="vertical" + selector: 'app-demo', + template: ` +
- ` + `, }) export class DemoComponent { - formData: any = { - id: 1 - }; - uiSchema: SFUISchema = {}; - schema: SFSchema = { - properties: { - 'time': { - 'type': 'string', - 'format': 'time' - }, - 'time_number': { - 'type': 'number', - ui: { widget: 'time', utcEpoch: true, displayFormat: 'HH:mm' } - }, - 'time_string': { - 'type': 'string', - ui: { widget: 'time' } - } - }, - ui: { - spanLabelFixed: 100 - } - }; + formData: any = { + id: 1, + time: new Date('1970-1-1 19:42:18'), + time_number: 70997000, + }; + uiSchema: SFUISchema = {}; + schema: SFSchema = { + properties: { + time: { + type: 'string', + format: 'time', + }, + time_number: { + type: 'number', + ui: { widget: 'time', utcEpoch: true, displayFormat: 'HH:mm' }, + }, + time_string: { + type: 'string', + ui: { widget: 'time' }, + }, + }, + ui: { + spanLabelFixed: 100, + }, + }; - constructor(private msg: NzMessageService, private http: _HttpClient) { - } + constructor(private msg: NzMessageService, private http: _HttpClient) {} - submit(value: any) { - this.msg.success(JSON.stringify(value)); - } + update() { + this.formData = { + id: 1, + time: new Date('1970-1-1 19:41:18'), + time_number: 71899000 + }; + } - change(value: any) { - // console.log('change', value); - } + submit(value: any) { + this.msg.success(JSON.stringify(value)); + } - error(value: any) { - console.log('error', value); - } + change(value: any) { + // console.log('change', value); + } + error(value: any) { + console.log('error', value); + } } diff --git a/tslint.json b/tslint.json index 881f16828c..c230bc3b91 100644 --- a/tslint.json +++ b/tslint.json @@ -94,5 +94,11 @@ "component-class-suffix": false, "directive-class-suffix": true, "invoke-injectable": true + }, + "linterOptions": { + "exclude": [ + "packages/**/*.spec.ts", + "packages/cli/**/*" + ] } }