Skip to content
This repository was archived by the owner on Mar 5, 2024. It is now read-only.

Commit 90cf507

Browse files
authored
Merge pull request #273 from BTMorton/config_change_detection
Fix some issues with change detection of user configs.
2 parents 81fb3ba + 4428ef4 commit 90cf507

File tree

3 files changed

+98
-54
lines changed

3 files changed

+98
-54
lines changed

rollup.config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@ export default {
1212
'rxjs/add/operator/mergeMap': 'Rx.Observable.prototype',
1313
'rxjs/add/observable/fromEvent': 'Rx.Observable',
1414
'rxjs/add/observable/of': 'Rx.Observable'
15-
}
15+
},
16+
external: [
17+
"@angular/core",
18+
]
1619
}

src/directives/NgGrid.ts

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy {
8282
private _elementBasedDynamicRowHeight: boolean = false;
8383
private _itemFixDirection: NgConfigFixDirection = "cascade";
8484
private _collisionFixDirection: NgConfigFixDirection = "cascade";
85+
private _cascadePromise: Promise<void>;
8586

8687
// Default config
8788
private static CONST_DEFAULT_CONFIG: NgGridConfig = {
@@ -118,6 +119,8 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy {
118119
if (this._differ == null && v != null) {
119120
this._differ = this._differs.find(this._config).create(null);
120121
}
122+
123+
this._differ.diff(this._config);
121124
}
122125

123126
// Constructor
@@ -382,10 +385,13 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy {
382385

383386
this._updateSize();
384387

385-
ngItem.recalculateSelf();
386-
ngItem.onCascadeEvent();
388+
this.triggerCascade().then(() => {
389+
ngItem.recalculateSelf();
390+
ngItem.onCascadeEvent();
391+
392+
this._emitOnItemChange();
393+
});
387394

388-
this._emitOnItemChange();
389395
}
390396

391397
public removeItem(ngItem: NgGridItem): void {
@@ -395,22 +401,35 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy {
395401

396402
if (this._destroyed) return;
397403

398-
this._cascadeGrid();
399-
this._updateSize();
400-
this._items.forEach((item: NgGridItem) => item.recalculateSelf());
401-
this._emitOnItemChange();
404+
this.triggerCascade().then(() => {
405+
this._updateSize();
406+
this._items.forEach((item: NgGridItem) => item.recalculateSelf());
407+
this._emitOnItemChange();
408+
});
402409
}
403410

404411
public updateItem(ngItem: NgGridItem): void {
405412
this._removeFromGrid(ngItem);
406413
this._addToGrid(ngItem);
407-
this._cascadeGrid();
408-
this._updateSize();
409-
ngItem.onCascadeEvent();
414+
415+
this.triggerCascade().then(() => {
416+
this._updateSize();
417+
ngItem.onCascadeEvent();
418+
});
410419
}
411420

412-
public triggerCascade(): void {
413-
this._cascadeGrid(null, null);
421+
public triggerCascade(): Promise<void> {
422+
if (!this._cascadePromise) {
423+
this._cascadePromise = new Promise((resolve: Function) => {
424+
setTimeout(() => {
425+
this._cascadePromise = null;
426+
this._cascadeGrid(null, null);
427+
resolve();
428+
}, 0);
429+
});
430+
}
431+
432+
return this._cascadePromise;
414433
}
415434

416435
public triggerResize(): void {
@@ -1048,55 +1067,60 @@ export class NgGrid implements OnInit, DoCheck, OnDestroy {
10481067

10491068
const maxRow = this._maxRows === 0 ? this._getMaxRow() : this._maxRows;
10501069
const maxCol = this._maxCols === 0 ? this._getMaxCol() : this._maxCols;
1070+
const newPos = {
1071+
col: pos.col,
1072+
row: pos.row,
1073+
};
1074+
10511075
if (this._itemFixDirection === "vertical") {
10521076
fixLoop:
1053-
for (; pos.col <= maxRow;) {
1054-
const itemsInPath = this._getItemsInVerticalPath(pos, dims, pos.row);
1055-
let nextRow = pos.row;
1077+
for (; newPos.col <= maxRow;) {
1078+
const itemsInPath = this._getItemsInVerticalPath(newPos, dims, newPos.row);
1079+
let nextRow = newPos.row;
10561080

10571081
for (let item of itemsInPath) {
10581082
if (item.row - nextRow >= dims.y) {
1059-
pos.row = nextRow;
1083+
newPos.row = nextRow;
10601084
break fixLoop;
10611085
}
10621086

10631087
nextRow = item.row + item.sizey;
10641088
}
10651089

10661090
if (maxRow - nextRow >= dims.y) {
1067-
pos.row = nextRow;
1091+
newPos.row = nextRow;
10681092
break fixLoop;
10691093
}
10701094

1071-
pos.col = Math.max(pos.col + 1, Math.min.apply(Math, itemsInPath.map((item) => item.col + dims.x)));
1072-
pos.row = 1;
1095+
newPos.col = Math.max(newPos.col + 1, Math.min.apply(Math, itemsInPath.map((item) => item.col + dims.x)));
1096+
newPos.row = 1;
10731097
}
10741098
} else if (this._itemFixDirection === "horizontal") {
10751099
fixLoop:
1076-
for (; pos.row <= maxRow;) {
1077-
const itemsInPath = this._getItemsInHorizontalPath(pos, dims, pos.col);
1078-
let nextCol = pos.col;
1100+
for (; newPos.row <= maxRow;) {
1101+
const itemsInPath = this._getItemsInHorizontalPath(newPos, dims, newPos.col);
1102+
let nextCol = newPos.col;
10791103

10801104
for (let item of itemsInPath) {
10811105
if (item.col - nextCol >= dims.x) {
1082-
pos.col = nextCol;
1106+
newPos.col = nextCol;
10831107
break fixLoop;
10841108
}
10851109

10861110
nextCol = item.col + item.sizex;
10871111
}
10881112

10891113
if (maxCol - nextCol >= dims.x) {
1090-
pos.col = nextCol;
1114+
newPos.col = nextCol;
10911115
break fixLoop;
10921116
}
10931117

1094-
pos.row = Math.max(pos.row + 1, Math.min.apply(Math, itemsInPath.map((item) => item.row + dims.y)));
1095-
pos.col = 1;
1118+
newPos.row = Math.max(newPos.row + 1, Math.min.apply(Math, itemsInPath.map((item) => item.row + dims.y)));
1119+
newPos.col = 1;
10961120
}
10971121
}
10981122

1099-
return pos;
1123+
return newPos;
11001124
}
11011125

11021126
private _getItemsInHorizontalPath(pos: NgGridItemPosition, dims: NgGridItemSize, startColumn: number = 0): NgGridItem[] {

src/directives/NgGridItem.ts

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export class NgGridItem implements OnInit, OnDestroy {
5050
private _currentPosition: NgGridItemPosition = { col: 1, row: 1 };
5151
private _size: NgGridItemSize = { x: 1, y: 1 };
5252
private _config = NgGridItem.CONST_DEFAULT_CONFIG;
53+
private _userConfig = null;
5354
private _dragHandle: string;
5455
private _resizeHandle: string;
5556
private _borderSize: number;
@@ -68,17 +69,21 @@ export class NgGridItem implements OnInit, OnDestroy {
6869
// [ng-grid-item] handler
6970
set config(v: NgGridItemConfig) {
7071
const defaults = NgGridItem.CONST_DEFAULT_CONFIG;
72+
this._userConfig = v;
7173

74+
const configObject = Object.assign({}, v);
7275
for (let x in defaults)
73-
if (v[x] == null)
74-
v[x] = defaults[x];
76+
if (configObject[x] == null)
77+
configObject[x] = defaults[x];
7578

76-
this.setConfig(v);
79+
this.setConfig(configObject);
7780

78-
if (this._differ == null && v != null) {
79-
this._differ = this._differs.find(this._config).create(null);
81+
if (this._differ == null && configObject != null) {
82+
this._differ = this._differs.find(this._userConfig).create(null);
8083
}
8184

85+
this._differ.diff(this._userConfig);
86+
8287
if (!this._added) {
8388
this._added = true;
8489
this._ngGrid.addItem(this);
@@ -136,9 +141,9 @@ export class NgGridItem implements OnInit, OnDestroy {
136141
this.onChangeStop.emit(event);
137142
this.onChangeAny.emit(event);
138143

139-
this._config.sizex = this._size.x;
140-
this._config.sizey = this._size.y;
141-
this.ngGridItemChange.emit(this._config);
144+
this._config.sizex = this._userConfig.sizex = this._size.x;
145+
this._config.sizey = this._userConfig.sizey = this._size.y;
146+
this.ngGridItemChange.emit(this._userConfig);
142147
}
143148
public onDragStartEvent(): void {
144149
const event: NgGridItemEvent = this.getEventOutput();
@@ -161,16 +166,16 @@ export class NgGridItem implements OnInit, OnDestroy {
161166
this.onChangeStop.emit(event);
162167
this.onChangeAny.emit(event);
163168

164-
this._config.col = this._currentPosition.col;
165-
this._config.row = this._currentPosition.row;
166-
this.ngGridItemChange.emit(this._config);
169+
this._config.col = this._userConfig.col = this._currentPosition.col;
170+
this._config.row = this._userConfig.row = this._currentPosition.row;
171+
this.ngGridItemChange.emit(this._userConfig);
167172
}
168173
public onCascadeEvent(): void {
169-
this._config.sizex = this._size.x;
170-
this._config.sizey = this._size.y;
171-
this._config.col = this._currentPosition.col;
172-
this._config.row = this._currentPosition.row;
173-
this.ngGridItemChange.emit(this._config);
174+
this._config.sizex = this._userConfig.sizex = this._size.x;
175+
this._config.sizey = this._userConfig.sizey = this._size.y;
176+
this._config.col = this._userConfig.col = this._currentPosition.col;
177+
this._config.row = this._userConfig.row = this._currentPosition.row;
178+
this.ngGridItemChange.emit(this._userConfig);
174179
}
175180

176181
public ngOnInit(): void {
@@ -179,7 +184,7 @@ export class NgGridItem implements OnInit, OnDestroy {
179184
this._recalculateDimensions();
180185
this._recalculatePosition();
181186

182-
if (!this._added) {
187+
if (!this._added && this._userConfig != null) {
183188
this._added = true;
184189
this._ngGrid.addItem(this);
185190
}
@@ -332,12 +337,10 @@ export class NgGridItem implements OnInit, OnDestroy {
332337

333338
public ngDoCheck(): boolean {
334339
if (this._differ != null) {
335-
const changes: any = this._differ.diff(this._config);
340+
const changes: any = this._differ.diff(this._userConfig);
336341

337342
if (changes != null) {
338-
this._applyChanges(changes);
339-
340-
return true;
343+
return this._applyChanges(changes);
341344
}
342345
}
343346

@@ -520,11 +523,25 @@ export class NgGridItem implements OnInit, OnDestroy {
520523
};
521524
}
522525

523-
private _applyChanges(changes: any): void {
524-
changes.forEachAddedItem((record: any) => { this._config[record.key] = record.currentValue; });
525-
changes.forEachChangedItem((record: any) => { this._config[record.key] = record.currentValue; });
526-
changes.forEachRemovedItem((record: any) => { delete this._config[record.key]; });
526+
private _applyChanges(changes: any): boolean {
527+
let changed: boolean = false;
528+
const changeCheck = (record: any) => {
529+
if (this._config[record.key] !== record.currentValue) {
530+
this._config[record.key] = record.currentValue;
531+
changed = true;
532+
}
533+
};
534+
changes.forEachAddedItem(changeCheck);
535+
changes.forEachChangedItem(changeCheck);
536+
changes.forEachRemovedItem((record: any) => {
537+
changed = true;
538+
delete this._config[record.key];
539+
});
540+
541+
if (changed) {
542+
this.setConfig(this._config);
543+
}
527544

528-
this.setConfig(this._config);
545+
return changed;
529546
}
530547
}

0 commit comments

Comments
 (0)