X Tutup
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ export class DefaultIterableDiffer implements IterableDiffer {

onDestroy() {}

// todo(vicb): optim for UnmodifiableListView (frozen arrays)
check(collection: any): boolean {
this._reset();

Expand All @@ -119,24 +118,27 @@ export class DefaultIterableDiffer implements IterableDiffer {
var item;
var itemTrackBy;
if (isArray(collection)) {
var list = collection;
this._length = collection.length;

for (index = 0; index < this._length; index++) {
item = list[index];
itemTrackBy = this._trackByFn(index, item);
if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
record = this._mismatch(record, item, itemTrackBy, index);
mayBeDirty = true;
} else {
if (mayBeDirty) {
// TODO(misko): can we limit this to duplicates only?
record = this._verifyReinsertion(record, item, itemTrackBy, index);
if (collection !== this._collection || !ListWrapper.isImmutable(collection)) {
var list = collection;
this._length = collection.length;

for (index = 0; index < this._length; index++) {
item = list[index];
itemTrackBy = this._trackByFn(index, item);
if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
record = this._mismatch(record, item, itemTrackBy, index);
mayBeDirty = true;
} else {
if (mayBeDirty) {
// TODO(misko): can we limit this to duplicates only?
record = this._verifyReinsertion(record, item, itemTrackBy, index);
}
if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item);
}
if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item);
}

record = record._next;
record = record._next;
}
this._truncate(record);
}
} else {
index = 0;
Expand All @@ -156,9 +158,9 @@ export class DefaultIterableDiffer implements IterableDiffer {
index++;
});
this._length = index;
this._truncate(record);
}

this._truncate(record);
this._collection = collection;
return this.isDirty;
}
Expand Down
9 changes: 8 additions & 1 deletion modules/angular2/src/facade/collection.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
library facade.collection;

import 'dart:collection' show IterableBase;
import 'dart:collection' show IterableBase, UnmodifiableListView;
import 'dart:convert' show JsonEncoder;
export 'dart:core' show Iterator, Map, List, Set;
import 'dart:math' show max, min;
Expand Down Expand Up @@ -106,6 +106,9 @@ class ListWrapper {
static List createFixedSize(int size) => new List(size);
static List createGrowableSize(int size) =>
new List.generate(size, (_) => null, growable: true);
static UnmodifiableListView createImmutable(List input) {
return new UnmodifiableListView(input);
}

static bool contains(List m, k) => m.contains(k);
static int indexOf(List list, value, [int startIndex = 0]) =>
Expand Down Expand Up @@ -221,6 +224,10 @@ class ListWrapper {
}
return solution;
}

static bool isImmutable(List l) {
return l is UnmodifiableListView;
}
}

bool isListLikeIterable(obj) => obj is Iterable;
Expand Down
7 changes: 7 additions & 0 deletions modules/angular2/src/facade/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ export class ListWrapper {
static createFixedSize(size: number): any[] { return new Array(size); }
static createGrowableSize(size: number): any[] { return new Array(size); }
static clone<T>(array: T[]): T[] { return array.slice(0); }
static createImmutable<T>(array: T[]): T[] {
var result = ListWrapper.clone(array);
Object.seal(result);
return result;
}
static forEachWithIndex<T>(array: T[], fn: (t: T, n: number) => void) {
for (var i = 0; i < array.length; i++) {
fn(array[i], i);
Expand Down Expand Up @@ -265,6 +270,8 @@ export class ListWrapper {
}
return solution;
}

static isImmutable(list: any[]): boolean { return Object.isSealed(list); }
}

export function isListLikeIterable(obj: any): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class ComplexItem {
toString() { return `{id: ${this.id}, color: ${this.color}}` }
}

// todo(vicb): UnmodifiableListView / frozen object when implemented
export function main() {
describe('iterable differ', function() {
describe('DefaultIterableDiffer', function() {
Expand Down Expand Up @@ -314,6 +313,36 @@ export function main() {
}));
});

it('should not diff immutable collections if they are the same', () => {
// Note: Use trackBy to know if diffing happened
var trackByCount = 0;
var trackBy = (index: number, item: any): any => {
trackByCount++;
return item;
};
var differ = new DefaultIterableDiffer(trackBy);
var l1 = ListWrapper.createImmutable([1]);

differ.check(l1);
expect(trackByCount).toBe(1);
expect(differ.toString())
.toEqual(
iterableChangesAsString({collection: ['1[null->0]'], additions: ['1[null->0]']}));


trackByCount = 0;
differ.check(l1);
expect(trackByCount).toBe(0);
expect(differ.toString())
.toEqual(iterableChangesAsString({collection: ['1'], previous: ['1']}));

trackByCount = 0;
differ.check(l1);
expect(trackByCount).toBe(0);
expect(differ.toString())
.toEqual(iterableChangesAsString({collection: ['1'], previous: ['1']}));
});

describe('diff', () => {
it('should return self when there is a change',
() => { expect(differ.diff(['a', 'b'])).toBe(differ); });
Expand Down
X Tutup