From f6a410a4a8b7e81b225a6e82c0ecf43d1c3124a1 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Wed, 22 Jun 2016 13:13:31 -0700 Subject: [PATCH] feat(QueryList): implement some() (#9464) closes #9443 --- .../@angular/core/src/linker/query_list.ts | 43 +++++++----- .../core/test/linker/query_list_spec.ts | 68 ++++++++++--------- modules/@angular/facade/src/collection.ts | 2 +- tools/public_api_guard/public_api_spec.ts | 9 +-- 4 files changed, 67 insertions(+), 55 deletions(-) diff --git a/modules/@angular/core/src/linker/query_list.ts b/modules/@angular/core/src/linker/query_list.ts index cfdbaf609a..362cdca91e 100644 --- a/modules/@angular/core/src/linker/query_list.ts +++ b/modules/@angular/core/src/linker/query_list.ts @@ -2,8 +2,6 @@ import {EventEmitter, Observable} from '../facade/async'; import {ListWrapper} from '../facade/collection'; import {getSymbolIterator} from '../facade/lang'; - - /** * An unmodifiable list of items that Angular keeps up to date when the state * of the application changes. @@ -27,47 +25,56 @@ import {getSymbolIterator} from '../facade/lang'; * ``` * @stable */ -export class QueryList { +export class QueryList/* implements Iterable */ { private _dirty = true; private _results: Array = []; private _emitter = new EventEmitter(); get changes(): Observable { return this._emitter; } get length(): number { return this._results.length; } - get first(): T { return ListWrapper.first(this._results); } - get last(): T { return ListWrapper.last(this._results); } + get first(): T { return this._results[0]; } + get last(): T { return this._results[this.length - 1]; } /** - * returns a new array with the passed in function applied to each element. + * See + * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) */ - map(fn: (item: T, index?: number) => U): U[] { return this._results.map(fn); } + map(fn: (item: T, index: number, array: T[]) => U): U[] { return this._results.map(fn); } /** - * returns a filtered array. + * See + * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) */ - filter(fn: (item: T, index?: number) => boolean): T[] { return this._results.filter(fn); } + filter(fn: (item: T, index: number, array: T[]) => boolean): T[] { + return this._results.filter(fn); + } /** - * returns a reduced value. + * See + * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) */ - reduce(fn: (acc: U, item: T, index?: number) => U, init: U): U { + reduce(fn: (prevValue: U, curValue: T, curIndex: number, array: T[]) => U, init: U): U { return this._results.reduce(fn, init); } /** - * executes function for each element in a query. + * See + * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) */ - forEach(fn: (item: T, index?: number) => void): void { this._results.forEach(fn); } + forEach(fn: (item: T, index: number, array: T[]) => void): void { this._results.forEach(fn); } /** - * converts QueryList into an array + * See + * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) */ - toArray(): T[] { return ListWrapper.clone(this._results); } - - [getSymbolIterator()](): any { - return (this._results as any /** TODO #???? */)[getSymbolIterator()](); + some(fn: (value: T, index: number, array: T[]) => boolean): boolean { + return this._results.some(fn); } + toArray(): T[] { return this._results.slice(); } + + [getSymbolIterator()](): Iterator { return (this._results as any)[getSymbolIterator()](); } + toString(): string { return this._results.toString(); } reset(res: Array): void { diff --git a/modules/@angular/core/test/linker/query_list_spec.ts b/modules/@angular/core/test/linker/query_list_spec.ts index 67c45f976e..70ba732b7c 100644 --- a/modules/@angular/core/test/linker/query_list_spec.ts +++ b/modules/@angular/core/test/linker/query_list_spec.ts @@ -1,7 +1,7 @@ import {describe, it, expect, beforeEach, ddescribe, iit, xit,} from '@angular/core/testing/testing_internal'; import {fakeAsync, tick,} from '@angular/core/testing'; -import {MapWrapper, ListWrapper, iterateListLike} from '../../src/facade/collection'; -import {IS_DART, StringWrapper} from '../../src/facade/lang'; +import {iterateListLike} from '../../src/facade/collection'; +import {StringWrapper} from '../../src/facade/lang'; import {ObservableWrapper} from '../../src/facade/async'; import {QueryList} from '@angular/core/src/linker/query_list'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; @@ -59,41 +59,39 @@ export function main() { expect(join).toEqual('one0two1'); }); - if (!IS_DART) { - it('should support filter', () => { - queryList.reset(['one', 'two']); - expect((<_JsQueryList>queryList).filter((x: string) => x == 'one')).toEqual(['one']); - }); + it('should support filter', () => { + queryList.reset(['one', 'two']); + expect((<_JsQueryList>queryList).filter((x: string) => x == 'one')).toEqual(['one']); + }); - it('should support filter with index', () => { - queryList.reset(['one', 'two']); - expect((<_JsQueryList>queryList).filter((x: string, i: number) => i == 0)).toEqual(['one']); - }); + it('should support filter with index', () => { + queryList.reset(['one', 'two']); + expect((<_JsQueryList>queryList).filter((x: string, i: number) => i == 0)).toEqual(['one']); + }); - it('should support reduce', () => { - queryList.reset(['one', 'two']); - expect((<_JsQueryList>queryList).reduce((a: string, x: string) => a + x, 'start:')) - .toEqual('start:onetwo'); - }); + it('should support reduce', () => { + queryList.reset(['one', 'two']); + expect((<_JsQueryList>queryList).reduce((a: string, x: string) => a + x, 'start:')) + .toEqual('start:onetwo'); + }); - it('should support reduce with index', () => { - queryList.reset(['one', 'two']); - expect((<_JsQueryList>queryList) - .reduce((a: string, x: string, i: number) => a + x + i, 'start:')) - .toEqual('start:one0two1'); - }); + it('should support reduce with index', () => { + queryList.reset(['one', 'two']); + expect((<_JsQueryList>queryList) + .reduce((a: string, x: string, i: number) => a + x + i, 'start:')) + .toEqual('start:one0two1'); + }); - it('should support toArray', () => { - queryList.reset(['one', 'two']); - expect((<_JsQueryList>queryList).reduce((a: string, x: string) => a + x, 'start:')) - .toEqual('start:onetwo'); - }); + it('should support toArray', () => { + queryList.reset(['one', 'two']); + expect((<_JsQueryList>queryList).reduce((a: string, x: string) => a + x, 'start:')) + .toEqual('start:onetwo'); + }); - it('should support toArray', () => { - queryList.reset(['one', 'two']); - expect((<_JsQueryList>queryList).toArray()).toEqual(['one', 'two']); - }); - } + it('should support toArray', () => { + queryList.reset(['one', 'two']); + expect((<_JsQueryList>queryList).toArray()).toEqual(['one', 'two']); + }); it('should support toString', () => { queryList.reset(['one', 'two']); @@ -108,6 +106,12 @@ export function main() { expect(queryList.last).toEqual('three'); }); + it('should support some', () => { + queryList.reset(['one', 'two', 'three']); + expect(queryList.some(item => item === 'one')).toEqual(true); + expect(queryList.some(item => item === 'four')).toEqual(false); + }); + if (getDOM().supportsDOMEvents()) { describe('simple observable interface', () => { it('should fire callbacks on change', fakeAsync(() => { diff --git a/modules/@angular/facade/src/collection.ts b/modules/@angular/facade/src/collection.ts index cf67e2510d..0b9180a381 100644 --- a/modules/@angular/facade/src/collection.ts +++ b/modules/@angular/facade/src/collection.ts @@ -266,7 +266,7 @@ export class ListWrapper { } static flatten(list: Array): T[] { - var target: any[] /** TODO #???? */ = []; + var target: any[] = []; _flattenArray(list, target); return target; } diff --git a/tools/public_api_guard/public_api_spec.ts b/tools/public_api_guard/public_api_spec.ts index e30865d110..bf921dcaf1 100644 --- a/tools/public_api_guard/public_api_spec.ts +++ b/tools/public_api_guard/public_api_spec.ts @@ -417,16 +417,17 @@ const CORE = [ 'ProviderBuilder.toValue(value:any):Provider', 'QueryList.changes:Observable', 'QueryList.dirty:any', - 'QueryList.filter(fn:(item: T, index?: number) => boolean):T[]', + 'QueryList.filter(fn:(item: T, index: number, array: T[]) => boolean):T[]', 'QueryList.first:T', - 'QueryList.forEach(fn:(item: T, index?: number) => void):void', + 'QueryList.forEach(fn:(item: T, index: number, array: T[]) => void):void', 'QueryList.last:T', 'QueryList.length:number', - 'QueryList.map(fn:(item: T, index?: number) => U):U[]', + 'QueryList.map(fn:(item: T, index: number, array: T[]) => U):U[]', 'QueryList.notifyOnChanges():void', - 'QueryList.reduce(fn:(acc: U, item: T, index?: number) => U, init:U):U', + 'QueryList.reduce(fn:(prevValue: U, curValue: T, curIndex: number, array: T[]) => U, init:U):U', 'QueryList.reset(res:Array):void', 'QueryList.setDirty():any', + 'QueryList.some(fn:(value: T, index: number, array: T[]) => boolean):boolean', 'QueryList.toArray():T[]', 'QueryList.toString():string', 'QueryList',