feat(ivy): implement QueryList array-related methods (#21778)
PR Close #21778
This commit is contained in:
parent
bbb8f386f1
commit
f9381e42de
|
@ -12,6 +12,7 @@ import {Observable} from 'rxjs/Observable';
|
||||||
|
|
||||||
import {QueryList as viewEngine_QueryList} from '../linker/query_list';
|
import {QueryList as viewEngine_QueryList} from '../linker/query_list';
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
|
import {getSymbolIterator} from '../util';
|
||||||
|
|
||||||
import {assertEqual, assertNotNull} from './assert';
|
import {assertEqual, assertNotNull} from './assert';
|
||||||
import {ReadFromInjectorFn, getOrCreateNodeInjectorForNode} from './di';
|
import {ReadFromInjectorFn, getOrCreateNodeInjectorForNode} from './di';
|
||||||
|
@ -298,57 +299,77 @@ function createPredicate<T>(
|
||||||
class QueryList_<T>/* implements viewEngine_QueryList<T> */ {
|
class QueryList_<T>/* implements viewEngine_QueryList<T> */ {
|
||||||
readonly dirty = true;
|
readonly dirty = true;
|
||||||
readonly changes: Observable<T>;
|
readonly changes: Observable<T>;
|
||||||
private _values: T[]|null = null;
|
private _values: T[] = [];
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_valuesTree: any[] = [];
|
_valuesTree: any[] = [];
|
||||||
|
|
||||||
get length(): number {
|
get length(): number { return this._values.length; }
|
||||||
ngDevMode && assertNotNull(this._values, 'refreshed');
|
|
||||||
return this._values !.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
get first(): T|null {
|
get first(): T|null {
|
||||||
ngDevMode && assertNotNull(this._values, 'refreshed');
|
let values = this._values;
|
||||||
let values = this._values !;
|
|
||||||
return values.length ? values[0] : null;
|
return values.length ? values[0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get last(): T|null {
|
get last(): T|null {
|
||||||
ngDevMode && assertNotNull(this._values, 'refreshed');
|
let values = this._values;
|
||||||
let values = this._values !;
|
|
||||||
return values.length ? values[values.length - 1] : null;
|
return values.length ? values[values.length - 1] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<U>(fn: (item: T, index: number, array: T[]) => U): U[] {
|
/**
|
||||||
throw new Error('Method not implemented.');
|
* See
|
||||||
}
|
* [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
|
||||||
|
*/
|
||||||
|
map<U>(fn: (item: T, index: number, array: T[]) => U): U[] { return this._values.map(fn); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See
|
||||||
|
* [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
|
||||||
|
*/
|
||||||
filter(fn: (item: T, index: number, array: T[]) => boolean): T[] {
|
filter(fn: (item: T, index: number, array: T[]) => boolean): T[] {
|
||||||
throw new Error('Method not implemented.');
|
return this._values.filter(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See
|
||||||
|
* [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
|
||||||
|
*/
|
||||||
find(fn: (item: T, index: number, array: T[]) => boolean): T|undefined {
|
find(fn: (item: T, index: number, array: T[]) => boolean): T|undefined {
|
||||||
throw new Error('Method not implemented.');
|
return this._values.find(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See
|
||||||
|
* [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
|
||||||
|
*/
|
||||||
reduce<U>(fn: (prevValue: U, curValue: T, curIndex: number, array: T[]) => U, init: U): U {
|
reduce<U>(fn: (prevValue: U, curValue: T, curIndex: number, array: T[]) => U, init: U): U {
|
||||||
throw new Error('Method not implemented.');
|
return this._values.reduce(fn, init);
|
||||||
}
|
|
||||||
forEach(fn: (item: T, index: number, array: T[]) => void): void {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See
|
||||||
|
* [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
|
||||||
|
*/
|
||||||
|
forEach(fn: (item: T, index: number, array: T[]) => void): void { this._values.forEach(fn); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See
|
||||||
|
* [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
|
||||||
|
*/
|
||||||
some(fn: (value: T, index: number, array: T[]) => boolean): boolean {
|
some(fn: (value: T, index: number, array: T[]) => boolean): boolean {
|
||||||
throw new Error('Method not implemented.');
|
return this._values.some(fn);
|
||||||
}
|
|
||||||
toArray(): T[] {
|
|
||||||
ngDevMode && assertNotNull(this._values, 'refreshed');
|
|
||||||
return this._values !;
|
|
||||||
}
|
|
||||||
toString(): string {
|
|
||||||
ngDevMode && assertNotNull(this._values, 'refreshed');
|
|
||||||
return this._values !.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toArray(): T[] { return this._values.slice(0); }
|
||||||
|
|
||||||
|
[getSymbolIterator()](): Iterator<T> { return (this._values as any)[getSymbolIterator()](); }
|
||||||
|
|
||||||
|
toString(): string { return this._values.toString(); }
|
||||||
|
|
||||||
reset(res: (any[]|T)[]): void {
|
reset(res: (any[]|T)[]): void {
|
||||||
this._values = flatten(res);
|
this._values = flatten(res);
|
||||||
(this as{dirty: boolean}).dirty = false;
|
(this as{dirty: boolean}).dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyOnChanges(): void { throw new Error('Method not implemented.'); }
|
notifyOnChanges(): void { throw new Error('Method not implemented.'); }
|
||||||
setDirty(): void { (this as{dirty: boolean}).dirty = true; }
|
setDirty(): void { (this as{dirty: boolean}).dirty = true; }
|
||||||
destroy(): void { throw new Error('Method not implemented.'); }
|
destroy(): void { throw new Error('Method not implemented.'); }
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {QueryList} from '../../src/render3/query';
|
||||||
|
|
||||||
|
describe('QueryList', () => {
|
||||||
|
let q: QueryList<number>;
|
||||||
|
|
||||||
|
beforeEach(() => { q = new QueryList<number>(); });
|
||||||
|
|
||||||
|
describe('dirty and reset', () => {
|
||||||
|
|
||||||
|
it('should be dirty and empty initially', () => {
|
||||||
|
expect(q.dirty).toBeTruthy();
|
||||||
|
expect(q.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be not dirty after reset', () => {
|
||||||
|
expect(q.dirty).toBeTruthy();
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
expect(q.dirty).toBeFalsy();
|
||||||
|
expect(q.length).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('elements access', () => {
|
||||||
|
|
||||||
|
it('should give access to the first / last element', () => {
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
expect(q.length).toBe(3);
|
||||||
|
expect(q.first).toBe(1);
|
||||||
|
expect(q.last).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return copy of matched elements as an array', () => {
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
|
||||||
|
const result = q.toArray();
|
||||||
|
expect(result).toEqual([1, 2, 3]);
|
||||||
|
|
||||||
|
// mutate returned result to make sure that oryginal values in query are not mutated
|
||||||
|
result.push(4);
|
||||||
|
expect(q.toArray()).toEqual([1, 2, 3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('array-like methods', () => {
|
||||||
|
|
||||||
|
it('should support map method', () => {
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
expect(q.map<number>((item: number, idx: number) => {
|
||||||
|
return item + idx;
|
||||||
|
})).toEqual([1, 3, 5]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support filter method', () => {
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
expect(q.filter((item: number, idx: number) => { return item > 2; })).toEqual([3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support find method', () => {
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
expect(q.find((item: number, idx: number) => { return item > 0; })).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support reduce method', () => {
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
expect(q.reduce<number>((prevValue: number, curValue: number, curIndex: number) => {
|
||||||
|
return prevValue + curValue + curIndex;
|
||||||
|
}, 0)).toBe(9);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support forEach method', () => {
|
||||||
|
let itemIdxSum = 0;
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
q.forEach((item: number, idx: number) => { itemIdxSum += item + idx; });
|
||||||
|
expect(itemIdxSum).toBe(9);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support some method', () => {
|
||||||
|
q.reset([1, 2, 3]);
|
||||||
|
expect(q.some((item: number, idx: number) => { return item > 0; })).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in New Issue