X Tutup
Skip to content

Commit ab36ea0

Browse files
karavsavkin
authored andcommitted
fix(differ): clean up stale identity change refs
Closes #7193
1 parent 8bb66a5 commit ab36ea0

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

modules/angular2/src/core/change_detection/differs/default_iterable_differ.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ export class DefaultIterableDiffer implements IterableDiffer {
325325
if (this._removalsTail !== null) {
326326
this._removalsTail._nextRemoved = null;
327327
}
328+
if (this._identityChangesTail !== null) {
329+
this._identityChangesTail._nextIdentityChange = null;
330+
}
328331
}
329332

330333
/** @internal */

modules/angular2/test/common/directives/ng_for_spec.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ export function main() {
365365
it('should not replace tracked items',
366366
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
367367
var template =
368-
`<template ngFor #item [ngForOf]="items" [ngForTrackBy]="customTrackBy" #i="index">
368+
`<template ngFor #item [ngForOf]="items" [ngForTrackBy]="trackById" #i="index">
369369
<p>{{items[i]}}</p>
370370
</template>`;
371371
tcb.overrideTemplate(TestComponent, template)
@@ -387,7 +387,7 @@ export function main() {
387387
it('should update implicit local variable on view',
388388
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
389389
var template =
390-
`<div><template ngFor #item [ngForOf]="items" [ngForTrackBy]="customTrackBy">{{item['color']}}</template></div>`;
390+
`<div><template ngFor #item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`;
391391
tcb.overrideTemplate(TestComponent, template)
392392
.createAsync(TestComponent)
393393
.then((fixture) => {
@@ -403,7 +403,7 @@ export function main() {
403403
it('should move items around and keep them updated ',
404404
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
405405
var template =
406-
`<div><template ngFor #item [ngForOf]="items" [ngForTrackBy]="customTrackBy">{{item['color']}}</template></div>`;
406+
`<div><template ngFor #item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`;
407407
tcb.overrideTemplate(TestComponent, template)
408408
.createAsync(TestComponent)
409409
.then((fixture) => {
@@ -418,6 +418,24 @@ export function main() {
418418
async.done();
419419
});
420420
}));
421+
422+
it('should handle added and removed items properly when tracking by index',
423+
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
424+
var template =
425+
`<div><template ngFor #item [ngForOf]="items" [ngForTrackBy]="trackByIndex">{{item}}</template></div>`;
426+
tcb.overrideTemplate(TestComponent, template)
427+
.createAsync(TestComponent)
428+
.then((fixture) => {
429+
fixture.debugElement.componentInstance.items = ['a', 'b', 'c', 'd'];
430+
fixture.detectChanges();
431+
fixture.debugElement.componentInstance.items = ['e', 'f', 'g', 'h'];
432+
fixture.detectChanges();
433+
fixture.debugElement.componentInstance.items = ['e', 'f', 'h'];
434+
fixture.detectChanges();
435+
expect(fixture.debugElement.nativeElement).toHaveText('efh');
436+
async.done();
437+
});
438+
}));
421439
});
422440
});
423441
}
@@ -432,7 +450,8 @@ class TestComponent {
432450
@ContentChild(TemplateRef) contentTpl: TemplateRef;
433451
items: any;
434452
constructor() { this.items = [1, 2]; }
435-
customTrackBy(index: number, item: any): string { return item['id']; }
453+
trackById(index: number, item: any): string { return item['id']; }
454+
trackByIndex(index: number, item: any): number { return index; }
436455
}
437456

438457
@Component({selector: 'outer-cmp'})

modules/angular2/test/core/change_detection/differs/default_iterable_differ_spec.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ export function main() {
338338
});
339339
});
340340

341-
describe('trackBy function', function() {
341+
describe('trackBy function by id', function() {
342342
var differ;
343343

344344
var trackByItemId = (index: number, item: any): any => item.id;
@@ -433,5 +433,29 @@ export function main() {
433433
}));
434434
});
435435
});
436+
describe('trackBy function by index', function() {
437+
var differ;
438+
439+
var trackByIndex = (index: number, item: any): number => index;
440+
441+
beforeEach(() => { differ = new DefaultIterableDiffer(trackByIndex); });
442+
443+
it('should track removals normally', () => {
444+
differ.check(['a', 'b', 'c', 'd']);
445+
differ.check(['e', 'f', 'g', 'h']);
446+
differ.check(['e', 'f', 'h']);
447+
448+
expect(differ.toString())
449+
.toEqual(iterableChangesAsString({
450+
collection: ['e', 'f', 'h'],
451+
previous: ['e', 'f', 'h', 'h[3->null]'],
452+
removals: ['h[3->null]'],
453+
identityChanges: ['h']
454+
}));
455+
});
456+
457+
});
458+
459+
436460
});
437461
}

0 commit comments

Comments
 (0)
X Tutup