fix(ivy): QueryList not instance of exported QueryList (#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 #27942
This commit is contained in:
Kristiyan Kostadinov
2019-01-05 14:43:58 +02:00
committed by Kara Erickson
parent 9de9c8ad03
commit c1dacdd890
6 changed files with 13 additions and 200 deletions

View File

@ -6,9 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ElementRef} from '@angular/core';
import {ElementRef, QueryList} from '@angular/core';
import {AttributeMarker, defineComponent, template, defineDirective, InheritDefinitionFeature, ProvidersFeature, NgOnChangesFeature, QueryList} from '../../src/render3/index';
import {AttributeMarker, defineComponent, template, defineDirective, InheritDefinitionFeature, ProvidersFeature, NgOnChangesFeature} from '../../src/render3/index';
import {allocHostVars, bind, directiveInject, element, elementEnd, elementProperty, elementStyleProp, elementStyling, elementStylingApply, elementStart, listener, load, text, textBinding, loadQueryList, registerContentQuery, elementHostAttrs} from '../../src/render3/instructions';
import {query, queryRefresh} from '../../src/render3/query';
import {RenderFlags} from '../../src/render3/interfaces/definition';

View File

@ -1,102 +0,0 @@
/**
* @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);
});
});
describe('destroy', () => {
it('should close all subscriptions', () => {
let completed = false;
q.changes.subscribe(() => {}, () => {}, () => { completed = true; });
q.destroy();
expect(completed).toBeTruthy();
});
});
});

View File

@ -7,10 +7,10 @@
*/
import {NgForOfContext} from '@angular/common';
import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
import {ElementRef, QueryList, TemplateRef, ViewContainerRef} from '@angular/core';
import {EventEmitter} from '../..';
import {AttributeMarker, ProvidersFeature, QueryList, defineComponent, defineDirective, detectChanges} from '../../src/render3/index';
import {AttributeMarker, ProvidersFeature, defineComponent, defineDirective, detectChanges} from '../../src/render3/index';
import {getNativeByIndex} from '../../src/render3/util';
import {bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadQueryList, reference, registerContentQuery, template, text} from '../../src/render3/instructions';

View File

@ -5,6 +5,7 @@
* 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 '@angular/core';
import {RenderFlags} from '@angular/core/src/render3';
import {defineComponent, getHostElement} from '../../../src/render3/index';
@ -12,7 +13,7 @@ import {element, elementEnd, elementStart, elementStyling, elementStylingApply,
import {PlayState, Player, PlayerHandler} from '../../../src/render3/interfaces/player';
import {RElement} from '../../../src/render3/interfaces/renderer';
import {addPlayer, getPlayers} from '../../../src/render3/players';
import {QueryList, query, queryRefresh} from '../../../src/render3/query';
import {query, queryRefresh} from '../../../src/render3/query';
import {getOrCreatePlayerContext} from '../../../src/render3/styling/util';
import {ComponentFixture} from '../render_util';