refactor: remove facade/collection (#14837)

This commit is contained in:
Miško Hevery
2017-03-01 14:10:59 -08:00
committed by Chuck Jazdzewski
parent 4fe0b90948
commit b0e0839075
27 changed files with 149 additions and 244 deletions

View File

@ -14,7 +14,6 @@ import {merge} from 'rxjs/observable/merge';
import {share} from 'rxjs/operator/share';
import {ErrorHandler} from '../src/error_handler';
import {ListWrapper} from '../src/facade/collection';
import {scheduleMicroTask, stringify} from '../src/facade/lang';
import {isPromise} from '../src/util/lang';
@ -300,7 +299,7 @@ export class PlatformRef_ extends PlatformRef {
if (!exceptionHandler) {
throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
}
moduleRef.onDestroy(() => ListWrapper.remove(this._modules, moduleRef));
moduleRef.onDestroy(() => remove(this._modules, moduleRef));
ngZone.onError.subscribe({next: (error: any) => { exceptionHandler.handleError(error); }});
return _callAndReportToErrorHandler(exceptionHandler, () => {
const initStatus: ApplicationInitStatus = moduleRef.injector.get(ApplicationInitStatus);
@ -489,7 +488,7 @@ export class ApplicationRef_ extends ApplicationRef {
detachView(viewRef: ViewRef): void {
const view = (viewRef as InternalViewRef);
ListWrapper.remove(this._views, view);
remove(this._views, view);
view.detachFromAppRef();
}
@ -533,7 +532,7 @@ export class ApplicationRef_ extends ApplicationRef {
private _unloadComponent(componentRef: ComponentRef<any>): void {
this.detachView(componentRef.hostView);
ListWrapper.remove(this._rootComponents, componentRef);
remove(this._rootComponents, componentRef);
}
tick(): void {
@ -567,3 +566,10 @@ export class ApplicationRef_ extends ApplicationRef {
get isStable(): Observable<boolean> { return this._isStable; }
}
function remove<T>(list: T[], el: T): void {
const index = list.indexOf(el);
if (index > -1) {
list.splice(index, 1);
}
}

View File

@ -6,8 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {areIterablesEqual, isListLikeIterable} from '../facade/collection';
import {isPrimitive, looseIdentical} from '../facade/lang';
import {getSymbolIterator, isJsObject, isPrimitive, looseIdentical} from '../facade/lang';
export {looseIdentical} from '../facade/lang';
@ -78,3 +77,38 @@ export class SimpleChange {
*/
isFirstChange(): boolean { return this.firstChange; }
}
export function isListLikeIterable(obj: any): boolean {
if (!isJsObject(obj)) return false;
return Array.isArray(obj) ||
(!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
}
export function areIterablesEqual(
a: any, b: any, comparator: (a: any, b: any) => boolean): boolean {
const iterator1 = a[getSymbolIterator()]();
const iterator2 = b[getSymbolIterator()]();
while (true) {
const item1 = iterator1.next();
const item2 = iterator2.next();
if (item1.done && item2.done) return true;
if (item1.done || item2.done) return false;
if (!comparator(item1.value, item2.value)) return false;
}
}
export function iterateListLike(obj: any, fn: (p: any) => any) {
if (Array.isArray(obj)) {
for (let i = 0; i < obj.length; i++) {
fn(obj[i]);
}
} else {
const iterator = obj[getSymbolIterator()]();
let item: any;
while (!((item = iterator.next()).done)) {
fn(item.value);
}
}
}

View File

@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {isListLikeIterable, iterateListLike} from '../../facade/collection';
import {isBlank, looseIdentical, stringify} from '../../facade/lang';
import {isListLikeIterable, iterateListLike} from '../change_detection_util';
import {ChangeDetectorRef} from '../change_detector_ref';
import {IterableChangeRecord, IterableChanges, IterableDiffer, IterableDifferFactory, NgIterable, TrackByFunction} from './iterable_differs';

View File

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import {StringMapWrapper} from '../../facade/collection';
import {isJsObject, looseIdentical, stringify} from '../../facade/lang';
import {ChangeDetectorRef} from '../change_detector_ref';

View File

@ -21,7 +21,7 @@ export {APP_INITIALIZER, ApplicationInitStatus} from './application_init';
export * from './zone';
export * from './render';
export * from './linker';
export {DebugElement, DebugNode, asNativeElements, getDebugNode} from './debug/debug_node';
export {DebugElement, DebugNode, asNativeElements, getDebugNode, Predicate} from './debug/debug_node';
export {GetTestability, Testability, TestabilityRegistry, setTestabilityGetter} from './testability/testability';
export * from './change_detection';
export * from './platform_core_providers';
@ -34,7 +34,6 @@ export {ErrorHandler} from './error_handler';
export * from './core_private_export';
export {Sanitizer, SecurityContext} from './security';
export * from './codegen_private_exports';
export * from './animation/animation_metadata_wrapped';
import {AnimationTriggerMetadata} from './animation/animation_metadata_wrapped';

View File

@ -9,6 +9,7 @@
export {ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS} from './application_ref';
export {APP_ID_RANDOM_PROVIDER as ɵAPP_ID_RANDOM_PROVIDER} from './application_tokens';
export {ValueUnwrapper as ɵValueUnwrapper, devModeEqual as ɵdevModeEqual} from './change_detection/change_detection_util';
export {isListLikeIterable as ɵisListLikeIterable} from './change_detection/change_detection_util';
export {ChangeDetectorStatus as ɵChangeDetectorStatus, isDefaultChangeDetectionStrategy as ɵisDefaultChangeDetectionStrategy} from './change_detection/constants';
export {Console as ɵConsole} from './console';
export {ERROR_COMPONENT_TYPE as ɵERROR_COMPONENT_TYPE} from './errors';
@ -23,4 +24,4 @@ export {ReflectorReader as ɵReflectorReader} from './reflection/reflector_reade
export {GetterFn as ɵGetterFn, MethodFn as ɵMethodFn, SetterFn as ɵSetterFn} from './reflection/types';
export {DirectRenderer as ɵDirectRenderer, RenderDebugInfo as ɵRenderDebugInfo} from './render/api';
export {makeDecorator as ɵmakeDecorator} from './util/decorators';
export {isObservable as ɵisObservable, isPromise as ɵisPromise} from './util/lang';
export {isObservable as ɵisObservable, isPromise as ɵisPromise, merge as ɵmerge} from './util/lang';

View File

@ -7,7 +7,6 @@
*/
import {Injector} from '../di';
import {Predicate} from '../facade/collection';
import {RenderDebugInfo} from '../render/api';
export class EventListener { constructor(public name: string, public callback: Function){}; }
@ -192,3 +191,11 @@ export function indexDebugNode(node: DebugNode) {
export function removeDebugNodeFromIndex(node: DebugNode) {
_nativeNodeToDebugNode.delete(node.nativeNode);
}
/**
* A boolean-valued function over a value, possibly including context information
* regarding that value's position in an array.
*
* @experimental All debugging apis are currently experimental.
*/
export interface Predicate<T> { (value: T, index?: number, array?: T[]): boolean; }

View File

@ -9,7 +9,6 @@
import {Observable} from 'rxjs/Observable';
import {EventEmitter} from '../event_emitter';
import {ListWrapper} from '../facade/collection';
import {getSymbolIterator} from '../facade/lang';
@ -95,7 +94,7 @@ export class QueryList<T>/* implements Iterable<T> */ {
toString(): string { return this._results.toString(); }
reset(res: Array<T|any[]>): void {
this._results = ListWrapper.flatten(res);
this._results = flatten(res);
this._dirty = false;
}
@ -107,3 +106,10 @@ export class QueryList<T>/* implements Iterable<T> */ {
/** internal */
get dirty() { return this._dirty; }
}
function flatten<T>(list: Array<T|T[]>): T[] {
return list.reduce((flat: any[], item: T | T[]): T[] => {
const flatItem = Array.isArray(item) ? flatten(item) : item;
return (<T[]>flat).concat(flatItem);
}, []);
}

View File

@ -24,3 +24,18 @@ export function isPromise(obj: any): obj is Promise<any> {
export function isObservable(obj: any | Observable<any>): obj is Observable<any> {
return !!(obj && obj[symbolObservable]);
}
// TODO(misko): replace with Object.assign once we require ES6.
export function merge<V>(m1: {[key: string]: V}, m2: {[key: string]: V}): {[key: string]: V} {
const m: {[key: string]: V} = {};
for (const k of Object.keys(m1)) {
m[k] = m1[k];
}
for (const k of Object.keys(m2)) {
m[k] = m2[k];
}
return m;
}

View File

@ -6,13 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
import {iterateListLike} from '@angular/core/src/change_detection/change_detection_util';
import {QueryList} from '@angular/core/src/linker/query_list';
import {fakeAsync, tick} from '@angular/core/testing';
import {beforeEach, describe, expect, it} from '@angular/core/testing/testing_internal';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {iterateListLike} from '../../src/facade/collection';
export function main() {
describe('QueryList', () => {
let queryList: QueryList<string>;

View File

@ -6,10 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ɵisPromise as isPromise} from '@angular/core';
import {ɵisPromise as isPromise, ɵmerge as merge} from '@angular/core';
import {AsyncTestCompleter} from './async_test_completer';
import {StringMapWrapper} from './facade/collection';
import {global} from './facade/lang';
import {getTestBed, inject} from './test_bed';
@ -197,7 +196,7 @@ export class SpyObject {
object = new SpyObject();
}
const m = StringMapWrapper.merge(config, overrides);
const m = merge(config, overrides);
Object.keys(m).forEach(key => { object.spy(key).and.returnValue(m[key]); });
return object;
}