@ -11,26 +11,16 @@ import {DefaultKeyValueDifferFactory} from './differs/default_keyvalue_differ';
|
||||
import {IterableDifferFactory, IterableDiffers} from './differs/iterable_differs';
|
||||
import {KeyValueDifferFactory, KeyValueDiffers} from './differs/keyvalue_differs';
|
||||
|
||||
export {WrappedValue, devModeEqual} from './change_detection_util';
|
||||
export {SimpleChange, SimpleChanges} from '../interface/simple_change';
|
||||
export {devModeEqual, WrappedValue} from './change_detection_util';
|
||||
export {ChangeDetectorRef} from './change_detector_ref';
|
||||
export {ChangeDetectionStrategy, ChangeDetectorStatus, isDefaultChangeDetectionStrategy} from './constants';
|
||||
export {DefaultIterableDifferFactory} from './differs/default_iterable_differ';
|
||||
export {DefaultIterableDiffer} from './differs/default_iterable_differ';
|
||||
export {DefaultKeyValueDifferFactory} from './differs/default_keyvalue_differ';
|
||||
export {
|
||||
CollectionChangeRecord,
|
||||
IterableChangeRecord,
|
||||
IterableChanges,
|
||||
IterableDiffer,
|
||||
IterableDifferFactory,
|
||||
IterableDiffers,
|
||||
NgIterable,
|
||||
TrackByFunction
|
||||
} from
|
||||
'./differs/iterable_differs';
|
||||
export {CollectionChangeRecord, IterableChangeRecord, IterableChanges, IterableDiffer, IterableDifferFactory, IterableDiffers, NgIterable, TrackByFunction} from './differs/iterable_differs';
|
||||
export {KeyValueChangeRecord, KeyValueChanges, KeyValueDiffer, KeyValueDifferFactory, KeyValueDiffers} from './differs/keyvalue_differs';
|
||||
export {PipeTransform} from './pipe_transform';
|
||||
export {SimpleChange, SimpleChanges} from '../interface/simple_change';
|
||||
|
||||
|
||||
|
||||
|
@ -49,19 +49,27 @@ export class WrappedValue {
|
||||
/** @deprecated from 5.3, use `unwrap()` instead - will switch to protected */
|
||||
wrapped: any;
|
||||
|
||||
constructor(value: any) { this.wrapped = value; }
|
||||
constructor(value: any) {
|
||||
this.wrapped = value;
|
||||
}
|
||||
|
||||
/** Creates a wrapped value. */
|
||||
static wrap(value: any): WrappedValue { return new WrappedValue(value); }
|
||||
static wrap(value: any): WrappedValue {
|
||||
return new WrappedValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying value of a wrapped value.
|
||||
* Returns the given `value` when it is not wrapped.
|
||||
**/
|
||||
static unwrap(value: any): any { return WrappedValue.isWrapped(value) ? value.wrapped : value; }
|
||||
static unwrap(value: any): any {
|
||||
return WrappedValue.isWrapped(value) ? value.wrapped : value;
|
||||
}
|
||||
|
||||
/** Returns true if `value` is a wrapped value. */
|
||||
static isWrapped(value: any): value is WrappedValue { return value instanceof WrappedValue; }
|
||||
static isWrapped(value: any): value is WrappedValue {
|
||||
return value instanceof WrappedValue;
|
||||
}
|
||||
}
|
||||
|
||||
export function isListLikeIterable(obj: any): boolean {
|
||||
|
@ -15,7 +15,9 @@ import {IterableChangeRecord, IterableChanges, IterableDiffer, IterableDifferFac
|
||||
|
||||
export class DefaultIterableDifferFactory implements IterableDifferFactory {
|
||||
constructor() {}
|
||||
supports(obj: Object|null|undefined): boolean { return isListLikeIterable(obj); }
|
||||
supports(obj: Object|null|undefined): boolean {
|
||||
return isListLikeIterable(obj);
|
||||
}
|
||||
|
||||
create<V>(trackByFn?: TrackByFunction<V>): DefaultIterableDiffer<V> {
|
||||
return new DefaultIterableDiffer<V>(trackByFn);
|
||||
@ -31,7 +33,7 @@ const trackByIdentity = (index: number, item: any) => item;
|
||||
export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> {
|
||||
public readonly length: number = 0;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
public readonly collection !: V[] | Iterable<V>| null;
|
||||
public readonly collection!: V[]|Iterable<V>|null;
|
||||
// Keeps track of the used records at any point in time (during & across `_check()` calls)
|
||||
private _linkedRecords: _DuplicateMap<V>|null = null;
|
||||
// Keeps track of the removed records at any point in time during `_check()` calls.
|
||||
@ -50,7 +52,9 @@ export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChan
|
||||
private _identityChangesTail: IterableChangeRecord_<V>|null = null;
|
||||
private _trackByFn: TrackByFunction<V>;
|
||||
|
||||
constructor(trackByFn?: TrackByFunction<V>) { this._trackByFn = trackByFn || trackByIdentity; }
|
||||
constructor(trackByFn?: TrackByFunction<V>) {
|
||||
this._trackByFn = trackByFn || trackByIdentity;
|
||||
}
|
||||
|
||||
forEachItem(fn: (record: IterableChangeRecord_<V>) => void) {
|
||||
let record: IterableChangeRecord_<V>|null;
|
||||
@ -71,9 +75,9 @@ export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChan
|
||||
// Order: remove, add, move
|
||||
const record: IterableChangeRecord<V> = !nextRemove ||
|
||||
nextIt &&
|
||||
nextIt.currentIndex ! <
|
||||
nextIt.currentIndex! <
|
||||
getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ?
|
||||
nextIt ! :
|
||||
nextIt! :
|
||||
nextRemove;
|
||||
const adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
|
||||
const currentIndex = record.currentIndex;
|
||||
@ -83,14 +87,14 @@ export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChan
|
||||
addRemoveOffset--;
|
||||
nextRemove = nextRemove._nextRemoved;
|
||||
} else {
|
||||
nextIt = nextIt !._next;
|
||||
nextIt = nextIt!._next;
|
||||
if (record.previousIndex == null) {
|
||||
addRemoveOffset++;
|
||||
} else {
|
||||
// INVARIANT: currentIndex < previousIndex
|
||||
if (!moveOffsets) moveOffsets = [];
|
||||
const localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
|
||||
const localCurrentIndex = currentIndex ! - addRemoveOffset;
|
||||
const localCurrentIndex = currentIndex! - addRemoveOffset;
|
||||
if (localMovePreviousIndex != localCurrentIndex) {
|
||||
for (let i = 0; i < localMovePreviousIndex; i++) {
|
||||
const offset = i < moveOffsets.length ? moveOffsets[i] : (moveOffsets[i] = 0);
|
||||
@ -171,7 +175,7 @@ export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChan
|
||||
let item: V;
|
||||
let itemTrackBy: any;
|
||||
if (Array.isArray(collection)) {
|
||||
(this as{length: number}).length = collection.length;
|
||||
(this as {length: number}).length = collection.length;
|
||||
|
||||
for (let index = 0; index < this.length; index++) {
|
||||
item = collection[index];
|
||||
@ -206,11 +210,11 @@ export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChan
|
||||
record = record._next;
|
||||
index++;
|
||||
});
|
||||
(this as{length: number}).length = index;
|
||||
(this as {length: number}).length = index;
|
||||
}
|
||||
|
||||
this._truncate(record);
|
||||
(this as{collection: V[] | Iterable<V>}).collection = collection;
|
||||
(this as {collection: V[] | Iterable<V>}).collection = collection;
|
||||
return this.isDirty;
|
||||
}
|
||||
|
||||
@ -338,7 +342,7 @@ export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChan
|
||||
let reinsertRecord: IterableChangeRecord_<V>|null =
|
||||
this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
|
||||
if (reinsertRecord !== null) {
|
||||
record = this._reinsertAfter(reinsertRecord, record._prev !, index);
|
||||
record = this._reinsertAfter(reinsertRecord, record._prev!, index);
|
||||
} else if (record.currentIndex != index) {
|
||||
record.currentIndex = index;
|
||||
this._addToMoves(record, index);
|
||||
@ -611,7 +615,7 @@ class _DuplicateItemRecordList<V> {
|
||||
// TODO(vicb):
|
||||
// assert(record.item == _head.item ||
|
||||
// record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
|
||||
this._tail !._nextDup = record;
|
||||
this._tail!._nextDup = record;
|
||||
record._prevDup = this._tail;
|
||||
record._nextDup = null;
|
||||
this._tail = record;
|
||||
@ -623,7 +627,7 @@ class _DuplicateItemRecordList<V> {
|
||||
get(trackById: any, atOrAfterIndex: number|null): IterableChangeRecord_<V>|null {
|
||||
let record: IterableChangeRecord_<V>|null;
|
||||
for (record = this._head; record !== null; record = record._nextDup) {
|
||||
if ((atOrAfterIndex === null || atOrAfterIndex <= record.currentIndex !) &&
|
||||
if ((atOrAfterIndex === null || atOrAfterIndex <= record.currentIndex!) &&
|
||||
looseIdentical(record.trackById, trackById)) {
|
||||
return record;
|
||||
}
|
||||
@ -696,7 +700,7 @@ class _DuplicateMap<V> {
|
||||
*/
|
||||
remove(record: IterableChangeRecord_<V>): IterableChangeRecord_<V> {
|
||||
const key = record.trackById;
|
||||
const recordList: _DuplicateItemRecordList<V> = this.map.get(key) !;
|
||||
const recordList: _DuplicateItemRecordList<V> = this.map.get(key)!;
|
||||
// Remove the list of duplicates when it gets empty
|
||||
if (recordList.remove(record)) {
|
||||
this.map.delete(key);
|
||||
@ -704,13 +708,16 @@ class _DuplicateMap<V> {
|
||||
return record;
|
||||
}
|
||||
|
||||
get isEmpty(): boolean { return this.map.size === 0; }
|
||||
get isEmpty(): boolean {
|
||||
return this.map.size === 0;
|
||||
}
|
||||
|
||||
clear() { this.map.clear(); }
|
||||
clear() {
|
||||
this.map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
function getPreviousIndex(
|
||||
item: any, addRemoveOffset: number, moveOffsets: number[] | null): number {
|
||||
function getPreviousIndex(item: any, addRemoveOffset: number, moveOffsets: number[]|null): number {
|
||||
const previousIndex = item.previousIndex;
|
||||
if (previousIndex === null) return previousIndex;
|
||||
let moveOffset = 0;
|
||||
|
@ -14,9 +14,13 @@ import {KeyValueChangeRecord, KeyValueChanges, KeyValueDiffer, KeyValueDifferFac
|
||||
|
||||
export class DefaultKeyValueDifferFactory<K, V> implements KeyValueDifferFactory {
|
||||
constructor() {}
|
||||
supports(obj: any): boolean { return obj instanceof Map || isJsObject(obj); }
|
||||
supports(obj: any): boolean {
|
||||
return obj instanceof Map || isJsObject(obj);
|
||||
}
|
||||
|
||||
create<K, V>(): KeyValueDiffer<K, V> { return new DefaultKeyValueDiffer<K, V>(); }
|
||||
create<K, V>(): KeyValueDiffer<K, V> {
|
||||
return new DefaultKeyValueDiffer<K, V>();
|
||||
}
|
||||
}
|
||||
|
||||
export class DefaultKeyValueDiffer<K, V> implements KeyValueDiffer<K, V>, KeyValueChanges<K, V> {
|
||||
@ -175,7 +179,7 @@ export class DefaultKeyValueDiffer<K, V> implements KeyValueDiffer<K, V>, KeyVal
|
||||
|
||||
private _getOrCreateRecordForKey(key: K, value: V): KeyValueChangeRecord_<K, V> {
|
||||
if (this._records.has(key)) {
|
||||
const record = this._records.get(key) !;
|
||||
const record = this._records.get(key)!;
|
||||
this._maybeAddToChanges(record, value);
|
||||
const prev = record._prev;
|
||||
const next = record._next;
|
||||
@ -236,7 +240,7 @@ export class DefaultKeyValueDiffer<K, V> implements KeyValueDiffer<K, V>, KeyVal
|
||||
if (this._additionsHead === null) {
|
||||
this._additionsHead = this._additionsTail = record;
|
||||
} else {
|
||||
this._additionsTail !._nextAdded = record;
|
||||
this._additionsTail!._nextAdded = record;
|
||||
this._additionsTail = record;
|
||||
}
|
||||
}
|
||||
@ -245,7 +249,7 @@ export class DefaultKeyValueDiffer<K, V> implements KeyValueDiffer<K, V>, KeyVal
|
||||
if (this._changesHead === null) {
|
||||
this._changesHead = this._changesTail = record;
|
||||
} else {
|
||||
this._changesTail !._nextChanged = record;
|
||||
this._changesTail!._nextChanged = record;
|
||||
this._changesTail = record;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import {DefaultIterableDifferFactory} from '../differs/default_iterable_differ';
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export type NgIterable<T> = Array<T>| Iterable<T>;
|
||||
export type NgIterable<T> = Array<T>|Iterable<T>;
|
||||
|
||||
/**
|
||||
* A strategy for tracking changes over time to an iterable. Used by {@link NgForOf} to
|
||||
@ -86,8 +86,10 @@ export interface IterableChanges<V> {
|
||||
/** Iterate over all removed items. */
|
||||
forEachRemovedItem(fn: (record: IterableChangeRecord<V>) => void): void;
|
||||
|
||||
/** Iterate over all items which had their identity (as computed by the `TrackByFunction`)
|
||||
* changed. */
|
||||
/**
|
||||
* Iterate over all items which had their identity (as computed by the `TrackByFunction`)
|
||||
* changed.
|
||||
*/
|
||||
forEachIdentityChange(fn: (record: IterableChangeRecord<V>) => void): void;
|
||||
}
|
||||
|
||||
@ -124,7 +126,9 @@ export interface CollectionChangeRecord<V> extends IterableChangeRecord<V> {}
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export interface TrackByFunction<T> { (index: number, item: T): any; }
|
||||
export interface TrackByFunction<T> {
|
||||
(index: number, item: T): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a factory for {@link IterableDiffer}.
|
||||
@ -153,7 +157,9 @@ export class IterableDiffers {
|
||||
* @deprecated v4.0.0 - Should be private
|
||||
*/
|
||||
factories: IterableDifferFactory[];
|
||||
constructor(factories: IterableDifferFactory[]) { this.factories = factories; }
|
||||
constructor(factories: IterableDifferFactory[]) {
|
||||
this.factories = factories;
|
||||
}
|
||||
|
||||
static create(factories: IterableDifferFactory[], parent?: IterableDiffers): IterableDiffers {
|
||||
if (parent != null) {
|
||||
@ -206,8 +212,8 @@ export class IterableDiffers {
|
||||
if (factory != null) {
|
||||
return factory;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Cannot find a differ supporting object '${iterable}' of type '${getTypeNameForDebugging(iterable)}'`);
|
||||
throw new Error(`Cannot find a differ supporting object '${iterable}' of type '${
|
||||
getTypeNameForDebugging(iterable)}'`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,9 @@ export class KeyValueDiffers {
|
||||
*/
|
||||
factories: KeyValueDifferFactory[];
|
||||
|
||||
constructor(factories: KeyValueDifferFactory[]) { this.factories = factories; }
|
||||
constructor(factories: KeyValueDifferFactory[]) {
|
||||
this.factories = factories;
|
||||
}
|
||||
|
||||
static create<S>(factories: KeyValueDifferFactory[], parent?: KeyValueDiffers): KeyValueDiffers {
|
||||
if (parent) {
|
||||
|
@ -30,4 +30,6 @@
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export interface PipeTransform { transform(value: any, ...args: any[]): any; }
|
||||
export interface PipeTransform {
|
||||
transform(value: any, ...args: any[]): any;
|
||||
}
|
||||
|
Reference in New Issue
Block a user