diff --git a/rollup.config.js b/rollup.config.js index d27632f..039ba2a 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -12,5 +12,8 @@ export default { 'rxjs/add/operator/mergeMap': 'Rx.Observable.prototype', 'rxjs/add/observable/fromEvent': 'Rx.Observable', 'rxjs/add/observable/of': 'Rx.Observable' - } + }, + external: [ + "@angular/core", + ] } diff --git a/src/directives/NgGrid.ts b/src/directives/NgGrid.ts index 727ed61..fbfbfdd 100644 --- a/src/directives/NgGrid.ts +++ b/src/directives/NgGrid.ts @@ -82,6 +82,7 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy { private _elementBasedDynamicRowHeight: boolean = false; private _itemFixDirection: NgConfigFixDirection = "cascade"; private _collisionFixDirection: NgConfigFixDirection = "cascade"; + private _cascadePromise: Promise; // Default config private static CONST_DEFAULT_CONFIG: NgGridConfig = { @@ -118,6 +119,8 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy { if (this._differ == null && v != null) { this._differ = this._differs.find(this._config).create(null); } + + this._differ.diff(this._config); } // Constructor @@ -382,10 +385,13 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy { this._updateSize(); - ngItem.recalculateSelf(); - ngItem.onCascadeEvent(); + this.triggerCascade().then(() => { + ngItem.recalculateSelf(); + ngItem.onCascadeEvent(); + + this._emitOnItemChange(); + }); - this._emitOnItemChange(); } public removeItem(ngItem: NgGridItem): void { @@ -395,22 +401,35 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy { if (this._destroyed) return; - this._cascadeGrid(); - this._updateSize(); - this._items.forEach((item: NgGridItem) => item.recalculateSelf()); - this._emitOnItemChange(); + this.triggerCascade().then(() => { + this._updateSize(); + this._items.forEach((item: NgGridItem) => item.recalculateSelf()); + this._emitOnItemChange(); + }); } public updateItem(ngItem: NgGridItem): void { this._removeFromGrid(ngItem); this._addToGrid(ngItem); - this._cascadeGrid(); - this._updateSize(); - ngItem.onCascadeEvent(); + + this.triggerCascade().then(() => { + this._updateSize(); + ngItem.onCascadeEvent(); + }); } - public triggerCascade(): void { - this._cascadeGrid(null, null); + public triggerCascade(): Promise { + if (!this._cascadePromise) { + this._cascadePromise = new Promise((resolve: Function) => { + setTimeout(() => { + this._cascadePromise = null; + this._cascadeGrid(null, null); + resolve(); + }, 0); + }); + } + + return this._cascadePromise; } public triggerResize(): void { @@ -1048,15 +1067,20 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy { const maxRow = this._maxRows === 0 ? this._getMaxRow() : this._maxRows; const maxCol = this._maxCols === 0 ? this._getMaxCol() : this._maxCols; + const newPos = { + col: pos.col, + row: pos.row, + }; + if (this._itemFixDirection === "vertical") { fixLoop: - for (; pos.col <= maxRow;) { - const itemsInPath = this._getItemsInVerticalPath(pos, dims, pos.row); - let nextRow = pos.row; + for (; newPos.col <= maxRow;) { + const itemsInPath = this._getItemsInVerticalPath(newPos, dims, newPos.row); + let nextRow = newPos.row; for (let item of itemsInPath) { if (item.row - nextRow >= dims.y) { - pos.row = nextRow; + newPos.row = nextRow; break fixLoop; } @@ -1064,22 +1088,22 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy { } if (maxRow - nextRow >= dims.y) { - pos.row = nextRow; + newPos.row = nextRow; break fixLoop; } - pos.col = Math.max(pos.col + 1, Math.min.apply(Math, itemsInPath.map((item) => item.col + dims.x))); - pos.row = 1; + newPos.col = Math.max(newPos.col + 1, Math.min.apply(Math, itemsInPath.map((item) => item.col + dims.x))); + newPos.row = 1; } } else if (this._itemFixDirection === "horizontal") { fixLoop: - for (; pos.row <= maxRow;) { - const itemsInPath = this._getItemsInHorizontalPath(pos, dims, pos.col); - let nextCol = pos.col; + for (; newPos.row <= maxRow;) { + const itemsInPath = this._getItemsInHorizontalPath(newPos, dims, newPos.col); + let nextCol = newPos.col; for (let item of itemsInPath) { if (item.col - nextCol >= dims.x) { - pos.col = nextCol; + newPos.col = nextCol; break fixLoop; } @@ -1087,16 +1111,16 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy { } if (maxCol - nextCol >= dims.x) { - pos.col = nextCol; + newPos.col = nextCol; break fixLoop; } - pos.row = Math.max(pos.row + 1, Math.min.apply(Math, itemsInPath.map((item) => item.row + dims.y))); - pos.col = 1; + newPos.row = Math.max(newPos.row + 1, Math.min.apply(Math, itemsInPath.map((item) => item.row + dims.y))); + newPos.col = 1; } } - return pos; + return newPos; } private _getItemsInHorizontalPath(pos: NgGridItemPosition, dims: NgGridItemSize, startColumn: number = 0): NgGridItem[] { diff --git a/src/directives/NgGridItem.ts b/src/directives/NgGridItem.ts index 1a47c9e..79c275d 100644 --- a/src/directives/NgGridItem.ts +++ b/src/directives/NgGridItem.ts @@ -50,6 +50,7 @@ export class NgGridItem implements OnInit, OnDestroy { private _currentPosition: NgGridItemPosition = { col: 1, row: 1 }; private _size: NgGridItemSize = { x: 1, y: 1 }; private _config = NgGridItem.CONST_DEFAULT_CONFIG; + private _userConfig = null; private _dragHandle: string; private _resizeHandle: string; private _borderSize: number; @@ -68,17 +69,21 @@ export class NgGridItem implements OnInit, OnDestroy { // [ng-grid-item] handler set config(v: NgGridItemConfig) { const defaults = NgGridItem.CONST_DEFAULT_CONFIG; + this._userConfig = v; + const configObject = Object.assign({}, v); for (let x in defaults) - if (v[x] == null) - v[x] = defaults[x]; + if (configObject[x] == null) + configObject[x] = defaults[x]; - this.setConfig(v); + this.setConfig(configObject); - if (this._differ == null && v != null) { - this._differ = this._differs.find(this._config).create(null); + if (this._differ == null && configObject != null) { + this._differ = this._differs.find(this._userConfig).create(null); } + this._differ.diff(this._userConfig); + if (!this._added) { this._added = true; this._ngGrid.addItem(this); @@ -136,9 +141,9 @@ export class NgGridItem implements OnInit, OnDestroy { this.onChangeStop.emit(event); this.onChangeAny.emit(event); - this._config.sizex = this._size.x; - this._config.sizey = this._size.y; - this.ngGridItemChange.emit(this._config); + this._config.sizex = this._userConfig.sizex = this._size.x; + this._config.sizey = this._userConfig.sizey = this._size.y; + this.ngGridItemChange.emit(this._userConfig); } public onDragStartEvent(): void { const event: NgGridItemEvent = this.getEventOutput(); @@ -161,16 +166,16 @@ export class NgGridItem implements OnInit, OnDestroy { this.onChangeStop.emit(event); this.onChangeAny.emit(event); - this._config.col = this._currentPosition.col; - this._config.row = this._currentPosition.row; - this.ngGridItemChange.emit(this._config); + this._config.col = this._userConfig.col = this._currentPosition.col; + this._config.row = this._userConfig.row = this._currentPosition.row; + this.ngGridItemChange.emit(this._userConfig); } public onCascadeEvent(): void { - this._config.sizex = this._size.x; - this._config.sizey = this._size.y; - this._config.col = this._currentPosition.col; - this._config.row = this._currentPosition.row; - this.ngGridItemChange.emit(this._config); + this._config.sizex = this._userConfig.sizex = this._size.x; + this._config.sizey = this._userConfig.sizey = this._size.y; + this._config.col = this._userConfig.col = this._currentPosition.col; + this._config.row = this._userConfig.row = this._currentPosition.row; + this.ngGridItemChange.emit(this._userConfig); } public ngOnInit(): void { @@ -179,7 +184,7 @@ export class NgGridItem implements OnInit, OnDestroy { this._recalculateDimensions(); this._recalculatePosition(); - if (!this._added) { + if (!this._added && this._userConfig != null) { this._added = true; this._ngGrid.addItem(this); } @@ -332,12 +337,10 @@ export class NgGridItem implements OnInit, OnDestroy { public ngDoCheck(): boolean { if (this._differ != null) { - const changes: any = this._differ.diff(this._config); + const changes: any = this._differ.diff(this._userConfig); if (changes != null) { - this._applyChanges(changes); - - return true; + return this._applyChanges(changes); } } @@ -520,11 +523,25 @@ export class NgGridItem implements OnInit, OnDestroy { }; } - private _applyChanges(changes: any): void { - changes.forEachAddedItem((record: any) => { this._config[record.key] = record.currentValue; }); - changes.forEachChangedItem((record: any) => { this._config[record.key] = record.currentValue; }); - changes.forEachRemovedItem((record: any) => { delete this._config[record.key]; }); + private _applyChanges(changes: any): boolean { + let changed: boolean = false; + const changeCheck = (record: any) => { + if (this._config[record.key] !== record.currentValue) { + this._config[record.key] = record.currentValue; + changed = true; + } + }; + changes.forEachAddedItem(changeCheck); + changes.forEachChangedItem(changeCheck); + changes.forEachRemovedItem((record: any) => { + changed = true; + delete this._config[record.key]; + }); + + if (changed) { + this.setConfig(this._config); + } - this.setConfig(this._config); + return changed; } }