Skip to content

Commit c1dacdd

Browse files
crisbetokara
authored andcommitted
fix(ivy): QueryList not instance of exported QueryList (angular#27942)
Fixes Ivy's `QueryList` not being an instance of the exported ViewEnginer `QueryList`. Also reworks `first`, `last` and `length` to be regular properties, rather than setters. Reworking `length` was required to be able to extend the ViewEngine `QueryList`, but I reworked `first` and `last` as well since getters generate a lot more code when transpiled to ES5. These changes fix FW-706. PR Close angular#27942
1 parent 9de9c8a commit c1dacdd

File tree

6 files changed

+13
-200
lines changed

6 files changed

+13
-200
lines changed

packages/core/src/render3/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ export {
121121
} from './pipe';
122122

123123
export {
124-
QueryList,
125124
query,
126125
queryRefresh,
127126
} from './query';

packages/core/src/render3/query.ts

Lines changed: 7 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {Observable} from 'rxjs';
1212

1313
import {EventEmitter} from '../event_emitter';
1414
import {ElementRef as ViewEngine_ElementRef} from '../linker/element_ref';
15-
import {QueryList as viewEngine_QueryList} from '../linker/query_list';
15+
import {QueryList} from '../linker/query_list';
1616
import {TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref';
1717
import {Type} from '../type';
1818
import {getSymbolIterator} from '../util';
@@ -27,7 +27,7 @@ import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType, u
2727
import {LQueries, unusedValueExportToPlacateAjd as unused4} from './interfaces/query';
2828
import {LView, TVIEW} from './interfaces/view';
2929
import {getIsParent, getLView, getOrCreateCurrentQueries} from './state';
30-
import {flatten, isContentQueryHost} from './util';
30+
import {isContentQueryHost} from './util';
3131
import {createElementRef, createTemplateRef} from './view_engine_compatibility';
3232

3333
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4;
@@ -95,9 +95,8 @@ export class LQueries_ implements LQueries {
9595
public parent: LQueries_|null, private shallow: LQuery<any>|null,
9696
private deep: LQuery<any>|null) {}
9797

98-
track<T>(
99-
queryList: viewEngine_QueryList<T>, predicate: Type<T>|string[], descend?: boolean,
100-
read?: Type<T>): void {
98+
track<T>(queryList: QueryList<T>, predicate: Type<T>|string[], descend?: boolean, read?: Type<T>):
99+
void {
101100
if (descend) {
102101
this.deep = createQuery(this.deep, queryList, predicate, read != null ? read : null);
103102
} else {
@@ -355,92 +354,7 @@ function createQuery<T>(
355354
};
356355
}
357356

358-
class QueryList_<T>/* implements viewEngine_QueryList<T> */ {
359-
readonly dirty = true;
360-
readonly changes: Observable<T> = new EventEmitter();
361-
private _values: T[] = [];
362-
/** @internal */
363-
_valuesTree: any[] = [];
364-
365-
get length(): number { return this._values.length; }
366-
367-
get first(): T|null {
368-
let values = this._values;
369-
return values.length ? values[0] : null;
370-
}
371-
372-
get last(): T|null {
373-
let values = this._values;
374-
return values.length ? values[values.length - 1] : null;
375-
}
376-
377-
/**
378-
* See
379-
* [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
380-
*/
381-
map<U>(fn: (item: T, index: number, array: T[]) => U): U[] { return this._values.map(fn); }
382-
383-
/**
384-
* See
385-
* [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
386-
*/
387-
filter(fn: (item: T, index: number, array: T[]) => boolean): T[] {
388-
return this._values.filter(fn);
389-
}
390-
391-
/**
392-
* See
393-
* [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
394-
*/
395-
find(fn: (item: T, index: number, array: T[]) => boolean): T|undefined {
396-
return this._values.find(fn);
397-
}
398-
399-
/**
400-
* See
401-
* [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
402-
*/
403-
reduce<U>(fn: (prevValue: U, curValue: T, curIndex: number, array: T[]) => U, init: U): U {
404-
return this._values.reduce(fn, init);
405-
}
406-
407-
/**
408-
* See
409-
* [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
410-
*/
411-
forEach(fn: (item: T, index: number, array: T[]) => void): void { this._values.forEach(fn); }
412-
413-
/**
414-
* See
415-
* [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
416-
*/
417-
some(fn: (value: T, index: number, array: T[]) => boolean): boolean {
418-
return this._values.some(fn);
419-
}
420-
421-
toArray(): T[] { return this._values.slice(0); }
422-
423-
[getSymbolIterator()](): Iterator<T> { return (this._values as any)[getSymbolIterator()](); }
424-
425-
toString(): string { return this._values.toString(); }
426-
427-
reset(res: (any[]|T)[]): void {
428-
this._values = flatten(res);
429-
(this as{dirty: boolean}).dirty = false;
430-
}
431-
432-
notifyOnChanges(): void { (this.changes as EventEmitter<any>).emit(this); }
433-
setDirty(): void { (this as{dirty: boolean}).dirty = true; }
434-
destroy(): void {
435-
(this.changes as EventEmitter<any>).complete();
436-
(this.changes as EventEmitter<any>).unsubscribe();
437-
}
438-
}
439-
440-
// NOTE: this hack is here because IQueryList has private members and therefore
441-
// it can't be implemented only extended.
442-
export type QueryList<T> = viewEngine_QueryList<T>;
443-
export const QueryList: typeof viewEngine_QueryList = QueryList_ as any;
357+
type QueryList_<T> = QueryList<T>& {_valuesTree: any[]};
444358

445359
/**
446360
* Creates and returns a QueryList.
@@ -459,6 +373,7 @@ export function query<T>(
459373
ngDevMode && assertPreviousIsParent(getIsParent());
460374
const queryList = new QueryList<T>();
461375
const queries = getOrCreateCurrentQueries(LQueries_);
376+
(queryList as QueryList_<T>)._valuesTree = [];
462377
queries.track(queryList, predicate, descend, read);
463378
storeCleanupWithContext(getLView(), queryList, queryList.destroy);
464379
if (memoryIndex != null) {
@@ -475,7 +390,7 @@ export function query<T>(
475390
export function queryRefresh(queryList: QueryList<any>): boolean {
476391
const queryListImpl = (queryList as any as QueryList_<any>);
477392
if (queryList.dirty) {
478-
queryList.reset(queryListImpl._valuesTree);
393+
queryList.reset(queryListImpl._valuesTree || []);
479394
queryList.notifyOnChanges();
480395
return true;
481396
}

packages/core/test/render3/host_binding_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ElementRef} from '@angular/core';
9+
import {ElementRef, QueryList} from '@angular/core';
1010

11-
import {AttributeMarker, defineComponent, template, defineDirective, InheritDefinitionFeature, ProvidersFeature, NgOnChangesFeature, QueryList} from '../../src/render3/index';
11+
import {AttributeMarker, defineComponent, template, defineDirective, InheritDefinitionFeature, ProvidersFeature, NgOnChangesFeature} from '../../src/render3/index';
1212
import {allocHostVars, bind, directiveInject, element, elementEnd, elementProperty, elementStyleProp, elementStyling, elementStylingApply, elementStart, listener, load, text, textBinding, loadQueryList, registerContentQuery, elementHostAttrs} from '../../src/render3/instructions';
1313
import {query, queryRefresh} from '../../src/render3/query';
1414
import {RenderFlags} from '../../src/render3/interfaces/definition';

packages/core/test/render3/query_list_spec.ts

Lines changed: 0 additions & 102 deletions
This file was deleted.

packages/core/test/render3/query_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
*/
88

99
import {NgForOfContext} from '@angular/common';
10-
import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
10+
import {ElementRef, QueryList, TemplateRef, ViewContainerRef} from '@angular/core';
1111

1212
import {EventEmitter} from '../..';
13-
import {AttributeMarker, ProvidersFeature, QueryList, defineComponent, defineDirective, detectChanges} from '../../src/render3/index';
13+
import {AttributeMarker, ProvidersFeature, defineComponent, defineDirective, detectChanges} from '../../src/render3/index';
1414
import {getNativeByIndex} from '../../src/render3/util';
1515

1616
import {bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadQueryList, reference, registerContentQuery, template, text} from '../../src/render3/instructions';

packages/core/test/render3/styling/players_spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8+
import {QueryList} from '@angular/core';
89
import {RenderFlags} from '@angular/core/src/render3';
910

1011
import {defineComponent, getHostElement} from '../../../src/render3/index';
1112
import {element, elementEnd, elementStart, elementStyling, elementStylingApply, load, markDirty} from '../../../src/render3/instructions';
1213
import {PlayState, Player, PlayerHandler} from '../../../src/render3/interfaces/player';
1314
import {RElement} from '../../../src/render3/interfaces/renderer';
1415
import {addPlayer, getPlayers} from '../../../src/render3/players';
15-
import {QueryList, query, queryRefresh} from '../../../src/render3/query';
16+
import {query, queryRefresh} from '../../../src/render3/query';
1617
import {getOrCreatePlayerContext} from '../../../src/render3/styling/util';
1718
import {ComponentFixture} from '../render_util';
1819

0 commit comments

Comments
 (0)