fix(ngFor): update view locals if identity changes

Closes #6923
This commit is contained in:
Kara Erickson
2016-02-05 16:32:24 -08:00
committed by Kara
parent 6f1ef33e32
commit 0f10624b08
6 changed files with 146 additions and 37 deletions

View File

@ -25,6 +25,12 @@ class ItemWithId {
toString() { return `{id: ${this.id}}` }
}
class ComplexItem {
constructor(private id: string, private color: string) {}
toString() { return `{id: ${this.id}, color: ${this.color}}` }
}
// todo(vicb): UnmodifiableListView / frozen object when implemented
export function main() {
describe('iterable differ', function() {
@ -342,8 +348,12 @@ export function main() {
beforeEach(() => { differ = new DefaultIterableDiffer(trackByItemId); });
it('should not treat maps as new with track by function', () => {
it('should treat the collection as dirty if identity changes', () => {
differ.diff(buildItemList(['a']));
expect(differ.diff(buildItemList(['a']))).toBe(differ);
});
it('should treat seen records as identity changes, not additions', () => {
let l = buildItemList(['a', 'b', 'c']);
differ.check(l);
expect(differ.toString())
@ -357,11 +367,26 @@ export function main() {
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: [`{id: a}`, `{id: b}`, `{id: c}`],
identityChanges: [`{id: a}`, `{id: b}`, `{id: c}`],
previous: [`{id: a}`, `{id: b}`, `{id: c}`]
}));
});
it('should track moves normally with track by function', () => {
it('should have updated properties in identity change collection', () => {
let l = [new ComplexItem('a', 'blue'), new ComplexItem('b', 'yellow')];
differ.check(l);
l = [new ComplexItem('a', 'orange'), new ComplexItem('b', 'red')];
differ.check(l);
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: [`{id: a, color: orange}`, `{id: b, color: red}`],
identityChanges: [`{id: a, color: orange}`, `{id: b, color: red}`],
previous: [`{id: a, color: orange}`, `{id: b, color: red}`]
}));
});
it('should track moves normally', () => {
let l = buildItemList(['a', 'b', 'c']);
differ.check(l);
@ -370,13 +395,14 @@ export function main() {
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['{id: b}[1->0]', '{id: a}[0->1]', '{id: c}'],
identityChanges: ['{id: b}[1->0]', '{id: a}[0->1]', '{id: c}'],
previous: ['{id: a}[0->1]', '{id: b}[1->0]', '{id: c}'],
moves: ['{id: b}[1->0]', '{id: a}[0->1]']
}));
});
it('should track duplicate reinsertion normally with track by function', () => {
it('should track duplicate reinsertion normally', () => {
let l = buildItemList(['a', 'a']);
differ.check(l);
@ -385,6 +411,7 @@ export function main() {
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['{id: b}[null->0]', '{id: a}[0->1]', '{id: a}[1->2]'],
identityChanges: ['{id: a}[0->1]', '{id: a}[1->2]'],
previous: ['{id: a}[0->1]', '{id: a}[1->2]'],
moves: ['{id: a}[0->1]', '{id: a}[1->2]'],
additions: ['{id: b}[null->0]']
@ -392,7 +419,7 @@ export function main() {
});
it('should track removals normally with track by function', () => {
it('should track removals normally', () => {
let l = buildItemList(['a', 'b', 'c']);
differ.check(l);

View File

@ -1,11 +1,12 @@
import {isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
export function iterableChangesAsString({collection = CONST_EXPR([]), previous = CONST_EXPR([]),
additions = CONST_EXPR([]), moves = CONST_EXPR([]),
removals = CONST_EXPR([])}) {
export function iterableChangesAsString(
{collection = CONST_EXPR([]), previous = CONST_EXPR([]), additions = CONST_EXPR([]),
moves = CONST_EXPR([]), removals = CONST_EXPR([]), identityChanges = CONST_EXPR([])}) {
return "collection: " + collection.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" +
"additions: " + additions.join(', ') + "\n" + "moves: " + moves.join(', ') + "\n" +
"removals: " + removals.join(', ') + "\n";
"removals: " + removals.join(', ') + "\n" + "identityChanges: " +
identityChanges.join(', ') + "\n";
}
export function kvChangesAsString(