From 48751cceae281d5388c7de654ae5f379ef7a23cc Mon Sep 17 00:00:00 2001 From: Chuck Jazdzewski Date: Mon, 15 Aug 2016 16:07:55 -0700 Subject: [PATCH] refactor(core): Removed deprecated Query and ViewQuery (#10820) BREAKING CHANGE: previously deprecated Query and ViewQuery were removed; see deprecation notice for migration instructions. --- .../compiler-cli/src/static_reflector.ts | 4 - modules/@angular/core/src/metadata.ts | 203 ------------------ modules/@angular/core/src/metadata/di.ts | 30 ++- .../core/test/forward_ref_integration_spec.ts | 11 +- .../core/test/linker/integration_spec.ts | 9 +- .../test/linker/query_integration_spec.ts | 96 ++------- tools/public_api_guard/core/index.d.ts | 24 +-- 7 files changed, 40 insertions(+), 337 deletions(-) diff --git a/modules/@angular/compiler-cli/src/static_reflector.ts b/modules/@angular/compiler-cli/src/static_reflector.ts index 0286cb3662..be699ddc57 100644 --- a/modules/@angular/compiler-cli/src/static_reflector.ts +++ b/modules/@angular/compiler-cli/src/static_reflector.ts @@ -191,10 +191,6 @@ export class StaticReflector implements ReflectorReader { this.host.findDeclaration(diDecorators, 'Optional'), OptionalMetadata); this.registerDecoratorOrConstructor( this.host.findDeclaration(coreDecorators, 'Attribute'), AttributeMetadata); - this.registerDecoratorOrConstructor( - this.host.findDeclaration(coreDecorators, 'Query'), QueryMetadata); - this.registerDecoratorOrConstructor( - this.host.findDeclaration(coreDecorators, 'ViewQuery'), ViewQueryMetadata); this.registerDecoratorOrConstructor( this.host.findDeclaration(coreDecorators, 'ContentChild'), ContentChildMetadata); this.registerDecoratorOrConstructor( diff --git a/modules/@angular/core/src/metadata.ts b/modules/@angular/core/src/metadata.ts index f269eb03cb..b218102264 100644 --- a/modules/@angular/core/src/metadata.ts +++ b/modules/@angular/core/src/metadata.ts @@ -171,58 +171,6 @@ export interface AttributeMetadataFactory { new (name: string): AttributeMetadata; } -/** - * {@link QueryMetadata} factory for creating annotations, decorators or DSL. - * - * ### Example as TypeScript Decorator - * - * ``` - * import {Query, QueryList, Component} from '@angular/core'; - * - * @Component({...}) - * class MyComponent { - * constructor(@Query(SomeType) queryList: QueryList) { - * ... - * } - * } - * ``` - * - * ### Example as ES5 DSL - * - * ``` - * var MyComponent = ng - * .Component({...}) - * .Class({ - * constructor: [new ng.Query(SomeType), function(queryList) { - * ... - * }] - * }) - * ``` - * - * ### Example as ES5 annotation - * - * ``` - * var MyComponent = function(queryList) { - * ... - * }; - * - * MyComponent.annotations = [ - * new ng.Component({...}) - * ] - * MyComponent.parameters = [ - * [new ng.Query(SomeType)] - * ] - * ``` - * @deprecated - */ -export interface QueryMetadataFactory { - (selector: Type|Function|string, - {descendants, read}?: {descendants?: boolean, read?: any}): ParameterDecorator; - new ( - selector: Type|Function|string, - {descendants, read}?: {descendants?: boolean, read?: any}): QueryMetadata; -} - /** * Factory for {@link ContentChildren}. * @stable @@ -763,117 +711,6 @@ export var Directive: DirectiveMetadataFactory = */ export var Attribute: AttributeMetadataFactory = makeParamDecorator(AttributeMetadata); -// TODO(alexeagle): remove the duplication of this doc. It is copied from QueryMetadata. -/** - * Declares an injectable parameter to be a live list of directives or variable - * bindings from the content children of a directive. - * - * ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview)) - * - * Assume that `` component would like to get a list its children `` - * components as shown in this example: - * - * ```html - * - * ... - * {{o.text}} - * - * ``` - * - * The preferred solution is to query for `Pane` directives using this decorator. - * - * ```javascript - * @Component({ - * selector: 'pane', - * inputs: ['title'] - * }) - * class Pane { - * title:string; - * } - * - * @Component({ - * selector: 'tabs', - * template: ` - *
    - *
  • {{pane.title}}
  • - *
- * - * ` - * }) - * class Tabs { - * panes: QueryList; - * constructor(@Query(Pane) panes:QueryList) { - * this.panes = panes; - * } - * } - * ``` - * - * A query can look for variable bindings by passing in a string with desired binding symbol. - * - * ### Example ([live demo](http://plnkr.co/edit/sT2j25cH1dURAyBRCKx1?p=preview)) - * ```html - * - *
...
- *
- * - * @Component({ selector: 'seeker' }) - * class seeker { - * constructor(@Query('findme') elList: QueryList) {...} - * } - * ``` - * - * In this case the object that is injected depend on the type of the variable - * binding. It can be an ElementRef, a directive or a component. - * - * Passing in a comma separated list of variable bindings will query for all of them. - * - * ```html - * - *
...
- *
...
- *
- * - * @Component({ - * selector: 'seeker' - * }) - * class Seeker { - * constructor(@Query('findMe, findMeToo') elList: QueryList) {...} - * } - * ``` - * - * Configure whether query looks for direct children or all descendants - * of the querying element, by using the `descendants` parameter. - * It is set to `false` by default. - * - * ### Example ([live demo](http://plnkr.co/edit/wtGeB977bv7qvA5FTYl9?p=preview)) - * ```html - * - * a - * b - * - * c - * - * - * ``` - * - * When querying for items, the first container will see only `a` and `b` by default, - * but with `Query(TextDirective, {descendants: true})` it will see `c` too. - * - * The queried directives are kept in a depth-first pre-order with respect to their - * positions in the DOM. - * - * Query does not look deep into any subcomponent views. - * - * Query is updated as part of the change-detection cycle. Since change detection - * happens after construction of a directive, QueryList will always be empty when observed in the - * constructor. - * - * The injected object is an unmodifiable live list. - * See {@link QueryList} for more details. - * @deprecated - * @Annotation - */ -export var Query: QueryMetadataFactory = makeParamDecorator(QueryMetadata); // TODO(alexeagle): remove the duplication of this doc. It is copied from ContentChildrenMetadata. /** @@ -1094,46 +931,6 @@ export var ViewChildren: ViewChildrenMetadataFactory = makePropDecorator(ViewChi */ export var ViewChild: ViewChildMetadataFactory = makePropDecorator(ViewChildMetadata); -// TODO(alexeagle): remove the duplication of this doc. It is copied from ViewQueryMetadata. -/** - * Similar to {@link QueryMetadata}, but querying the component view, instead of - * the content children. - * - * ### Example ([live demo](http://plnkr.co/edit/eNsFHDf7YjyM6IzKxM1j?p=preview)) - * - * ```javascript - * @Component({ - * ..., - * template: ` - * a - * b - * c - * ` - * }) - * class MyComponent { - * shown: boolean; - * - * constructor(private @Query(Item) items:QueryList) { - * items.changes.subscribe(() => console.log(items.length)); - * } - * } - * ``` - * - * Supports the same querying parameters as {@link QueryMetadata}, except - * `descendants`. This always queries the whole view. - * - * As `shown` is flipped between true and false, items will contain zero of one - * items. - * - * Specifies that a {@link QueryList} should be injected. - * - * The injected object is an iterable and observable live list. - * See {@link QueryList} for more details. - * @deprecated - * @Annotation - */ -export var ViewQuery: QueryMetadataFactory = makeParamDecorator(ViewQueryMetadata); - // TODO(alexeagle): remove the duplication of this doc. It is copied from PipeMetadata. /** * Declare reusable pipe function. diff --git a/modules/@angular/core/src/metadata/di.ts b/modules/@angular/core/src/metadata/di.ts index bde121d52c..c233b10abd 100644 --- a/modules/@angular/core/src/metadata/di.ts +++ b/modules/@angular/core/src/metadata/di.ts @@ -117,10 +117,7 @@ export class AttributeMetadata extends DependencyMetadata { * ` * }) * class Tabs { - * panes: QueryList; - * constructor(@Query(Pane) panes:QueryList) { - * this.panes = panes; - * } + * @ContentChildren(Pane) panes: QueryList; * } * ``` * @@ -134,7 +131,7 @@ export class AttributeMetadata extends DependencyMetadata { * * @Component({ selector: 'seeker' }) * class Seeker { - * constructor(@Query('findme') elList: QueryList) {...} + * @ContentChildren('findme') elList; * } * ``` * @@ -153,7 +150,7 @@ export class AttributeMetadata extends DependencyMetadata { * selector: 'seeker' * }) * class Seeker { - * constructor(@Query('findMe, findMeToo') elList: QueryList) {...} + * @ContentChildren('findMe, findMeToo') elList: QueryList; * } * ``` * @@ -173,20 +170,20 @@ export class AttributeMetadata extends DependencyMetadata { * ``` * * When querying for items, the first container will see only `a` and `b` by default, - * but with `Query(TextDirective, {descendants: true})` it will see `c` too. + * but with `ContentChildren(TextDirective, {descendants: true})` it will see `c` too. * * The queried directives are kept in a depth-first pre-order with respect to their * positions in the DOM. * - * Query does not look deep into any subcomponent views. + * ContentChildren does not look deep into any subcomponent views. * - * Query is updated as part of the change-detection cycle. Since change detection + * ContentChildren is updated as part of the change-detection cycle. Since change detection * happens after construction of a directive, QueryList will always be empty when observed in the * constructor. * * The injected object is an unmodifiable live list. * See {@link QueryList} for more details. - * @deprecated + * @stable */ export class QueryMetadata extends DependencyMetadata { /** @@ -293,8 +290,8 @@ export class ContentChildMetadata extends QueryMetadata { } /** - * Similar to {@link QueryMetadata}, but querying the component view, instead of - * the content children. + * Similar to {@link ContentChildMetadata}, but querying the component view, instead + * of the content children. * * ### Example ([live demo](http://plnkr.co/edit/eNsFHDf7YjyM6IzKxM1j?p=preview)) * @@ -310,15 +307,12 @@ export class ContentChildMetadata extends QueryMetadata { * class MyComponent { * shown: boolean; * - * constructor(private @ViewQuery(Item) items:QueryList) { + * constructor(private @ViewChildren(Item) items:QueryList) { * items.changes.subscribe(() => console.log(items.length)); * } * } * ``` * - * Supports the same querying parameters as {@link QueryMetadata}, except - * `descendants`. This always queries the whole view. - * * As `shown` is flipped between true and false, items will contain zero of one * items. * @@ -326,7 +320,7 @@ export class ContentChildMetadata extends QueryMetadata { * * The injected object is an iterable and observable live list. * See {@link QueryList} for more details. - * @deprecated + * @stable */ export class ViewQueryMetadata extends QueryMetadata { constructor( @@ -339,7 +333,6 @@ export class ViewQueryMetadata extends QueryMetadata { * always `true` to differentiate it with {@link QueryMetadata}. */ get isViewQuery() { return true; } - toString(): string { return `@ViewQuery(${stringify(this.selector)})`; } } /** @@ -424,6 +417,7 @@ export class ViewChildrenMetadata extends ViewQueryMetadata { constructor(_selector: Type|string, {read = null}: {read?: any} = {}) { super(_selector, {descendants: true, read: read}); } + toString(): string { return `@ViewChildren(${stringify(this.selector)})`; } } /** diff --git a/modules/@angular/core/test/forward_ref_integration_spec.ts b/modules/@angular/core/test/forward_ref_integration_spec.ts index 755b08352c..d59a3e7bdf 100644 --- a/modules/@angular/core/test/forward_ref_integration_spec.ts +++ b/modules/@angular/core/test/forward_ref_integration_spec.ts @@ -7,7 +7,7 @@ */ import {NgFor} from '@angular/common'; -import {Component, Directive, Inject, Query, QueryList, asNativeElements, bind, forwardRef, provide, resolveForwardRef} from '@angular/core'; +import {Component, ContentChildren, Directive, Inject, QueryList, asNativeElements, bind, forwardRef, provide, resolveForwardRef} from '@angular/core'; import {TestComponentBuilder} from '@angular/core/testing'; import {AsyncTestCompleter, beforeEach, ddescribe, describe, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {expect} from '@angular/platform-browser/testing/matchers'; @@ -42,15 +42,10 @@ class App { template: `{{frame.name}}({{lock.name}})`, }) class Door { - locks: QueryList; + @ContentChildren(forwardRef(() => Lock)) locks: QueryList; frame: Frame; - constructor( - @Query(forwardRef(() => Lock)) locks: QueryList, - @Inject(forwardRef(() => Frame)) frame: Frame) { - this.frame = frame; - this.locks = locks; - } + constructor(@Inject(forwardRef(() => Frame)) frame: Frame) { this.frame = frame; } } class Frame { diff --git a/modules/@angular/core/test/linker/integration_spec.ts b/modules/@angular/core/test/linker/integration_spec.ts index 06a9077cb0..7dad99961f 100644 --- a/modules/@angular/core/test/linker/integration_spec.ts +++ b/modules/@angular/core/test/linker/integration_spec.ts @@ -16,7 +16,7 @@ import {QueryList} from '@angular/core/src/linker/query_list'; import {TemplateRef, TemplateRef_} from '@angular/core/src/linker/template_ref'; import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref'; import {EmbeddedViewRef} from '@angular/core/src/linker/view_ref'; -import {Attribute, Component, Directive, HostBinding, HostListener, Input, Output, Pipe, Query, ViewMetadata} from '@angular/core/src/metadata'; +import {Attribute, Component, ContentChildren, Directive, HostBinding, HostListener, Input, Output, Pipe, ViewMetadata} from '@angular/core/src/metadata'; import {Renderer} from '@angular/core/src/render'; import {ComponentFixture, TestBed, TestComponentBuilder, fakeAsync, tick} from '@angular/core/testing'; import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; @@ -2483,13 +2483,10 @@ class ToolbarViewContainer { directives: [ToolbarViewContainer, NgFor] }) class ToolbarComponent { - query: QueryList; + @ContentChildren(ToolbarPart) query: QueryList; ctxProp: string; - constructor(@Query(ToolbarPart) query: QueryList) { - this.ctxProp = 'hello world'; - this.query = query; - } + constructor() { this.ctxProp = 'hello world'; } } @Directive({selector: '[two-way]', inputs: ['control'], outputs: ['controlChange']}) diff --git a/modules/@angular/core/test/linker/query_integration_spec.ts b/modules/@angular/core/test/linker/query_integration_spec.ts index 4b2bb4e5d7..29a775f4d9 100644 --- a/modules/@angular/core/test/linker/query_integration_spec.ts +++ b/modules/@angular/core/test/linker/query_integration_spec.ts @@ -7,7 +7,7 @@ */ import {NgFor, NgIf} from '@angular/common'; -import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, ContentChild, ContentChildren, Directive, Query, QueryList, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, ViewQuery, asNativeElements} from '@angular/core'; +import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, ContentChild, ContentChildren, Directive, QueryList, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, asNativeElements} from '@angular/core'; import {TestComponentBuilder} from '@angular/core/testing'; import {AsyncTestCompleter, beforeEach, ddescribe, describe, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {expect} from '@angular/platform-browser/testing/matchers'; @@ -429,34 +429,6 @@ export function main() { }); })); - it('should notify child\'s query before notifying parent\'s query', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - var template = '' + - '' + - '
' + - '
' + - '
'; - - tcb.overrideTemplate(MyComp0, template).createAsync(MyComp0).then((view) => { - var q1 = view.debugElement.children[0].references['q1']; - var q2 = view.debugElement.children[0].children[0].references['q2']; - - var firedQ2 = false; - - q2.query.changes.subscribe({next: () => { firedQ2 = true; }}); - q1.query.changes.subscribe({ - next: () => { - expect(firedQ2).toBe(true); - async.done(); - } - }); - - view.detectChanges(); - }); - })); - it('should correctly clean-up when destroyed together with the directives it is querying', inject( [TestComponentBuilder, AsyncTestCompleter], @@ -907,8 +879,7 @@ class InertDirective { template: '
{{dir.text}}|' }) class NeedsQuery { - query: QueryList; - constructor(@Query(TextDirective) query: QueryList) { this.query = query; } + @ContentChildren(TextDirective) query: QueryList; } @Component({selector: 'needs-four-queries', template: ''}) @@ -925,18 +896,12 @@ class NeedsFourQueries { template: '
{{dir.text}}|
' }) class NeedsQueryDesc { - query: QueryList; - constructor(@Query(TextDirective, {descendants: true}) query: QueryList) { - this.query = query; - } + @ContentChildren(TextDirective, {descendants: true}) query: QueryList; } @Component({selector: 'needs-query-by-ref-binding', directives: [], template: ''}) class NeedsQueryByLabel { - query: QueryList; - constructor(@Query('textLabel', {descendants: true}) query: QueryList) { - this.query = query; - } + @ContentChildren('textLabel', {descendants: true}) query: QueryList; } @Component({ @@ -945,16 +910,12 @@ class NeedsQueryByLabel { template: '
text
' }) class NeedsViewQueryByLabel { - query: QueryList; - constructor(@ViewQuery('textLabel') query: QueryList) { this.query = query; } + @ViewChildren('textLabel') query: QueryList; } @Component({selector: 'needs-query-by-ref-bindings', directives: [], template: ''}) class NeedsQueryByTwoLabels { - query: QueryList; - constructor(@Query('textLabel1,textLabel2', {descendants: true}) query: QueryList) { - this.query = query; - } + @ContentChildren('textLabel1,textLabel2', {descendants: true}) query: QueryList; } @Component({ @@ -963,8 +924,7 @@ class NeedsQueryByTwoLabels { template: '
{{dir.text}}|
' }) class NeedsQueryAndProject { - query: QueryList; - constructor(@Query(TextDirective) query: QueryList) { this.query = query; } + @ContentChildren(TextDirective) query: QueryList; } @Component({ @@ -974,8 +934,7 @@ class NeedsQueryAndProject { '
' }) class NeedsViewQuery { - query: QueryList; - constructor(@ViewQuery(TextDirective) query: QueryList) { this.query = query; } + @ViewChildren(TextDirective) query: QueryList; } @Component({ @@ -985,11 +944,8 @@ class NeedsViewQuery { }) class NeedsViewQueryIf { show: boolean; - query: QueryList; - constructor(@ViewQuery(TextDirective) query: QueryList) { - this.query = query; - this.show = false; - } + @ViewChildren(TextDirective) query: QueryList; + constructor() { this.show = false; } } @@ -1000,11 +956,8 @@ class NeedsViewQueryIf { }) class NeedsViewQueryNestedIf { show: boolean; - query: QueryList; - constructor(@ViewQuery(TextDirective) query: QueryList) { - this.query = query; - this.show = true; - } + @ViewChildren(TextDirective) query: QueryList; + constructor() { this.show = true; } } @Component({ @@ -1015,12 +968,9 @@ class NeedsViewQueryNestedIf { '
' }) class NeedsViewQueryOrder { - query: QueryList; + @ViewChildren(TextDirective) query: QueryList; list: string[]; - constructor(@ViewQuery(TextDirective) query: QueryList) { - this.query = query; - this.list = ['2', '3']; - } + constructor() { this.list = ['2', '3']; } } @Component({ @@ -1031,24 +981,16 @@ class NeedsViewQueryOrder { '
' }) class NeedsViewQueryOrderWithParent { - query: QueryList; + @ViewChildren(TextDirective) query: QueryList; list: string[]; - constructor(@ViewQuery(TextDirective) query: QueryList) { - this.query = query; - this.list = ['2', '3']; - } + constructor() { this.list = ['2', '3']; } } @Component({selector: 'needs-tpl', template: ''}) class NeedsTpl { - viewQuery: QueryList>; - query: QueryList>; - constructor( - @ViewQuery(TemplateRef) viewQuery: QueryList>, - @Query(TemplateRef) query: QueryList>, public vc: ViewContainerRef) { - this.viewQuery = viewQuery; - this.query = query; - } + @ViewChildren(TemplateRef) viewQuery: QueryList>; + @ContentChildren(TemplateRef) query: QueryList>; + constructor(public vc: ViewContainerRef) {} } @Component({selector: 'needs-named-tpl', template: ''}) diff --git a/tools/public_api_guard/core/index.d.ts b/tools/public_api_guard/core/index.d.ts index ea5be1293c..3fc14c6f98 100644 --- a/tools/public_api_guard/core/index.d.ts +++ b/tools/public_api_guard/core/index.d.ts @@ -1013,9 +1013,6 @@ export declare class ProviderBuilder { toValue(value: any): Provider; } -/** @deprecated */ -export declare var Query: QueryMetadataFactory; - /** @stable */ export declare class QueryList { changes: Observable; @@ -1035,7 +1032,7 @@ export declare class QueryList { toString(): string; } -/** @deprecated */ +/** @stable */ export declare class QueryMetadata extends DependencyMetadata { descendants: boolean; first: boolean; @@ -1052,18 +1049,6 @@ export declare class QueryMetadata extends DependencyMetadata { toString(): string; } -/** @deprecated */ -export interface QueryMetadataFactory { - (selector: Type | Function | string, {descendants, read}?: { - descendants?: boolean; - read?: any; - }): ParameterDecorator; - new (selector: Type | Function | string, {descendants, read}?: { - descendants?: boolean; - read?: any; - }): QueryMetadata; -} - /** @stable */ export declare abstract class ReflectiveInjector implements Injector { parent: Injector; @@ -1327,6 +1312,7 @@ export declare class ViewChildrenMetadata extends ViewQueryMetadata { constructor(_selector: Type | string, {read}?: { read?: any; }); + toString(): string; } /** @stable */ @@ -1387,10 +1373,7 @@ export declare class ViewMetadata { }); } -/** @deprecated */ -export declare var ViewQuery: QueryMetadataFactory; - -/** @deprecated */ +/** @stable */ export declare class ViewQueryMetadata extends QueryMetadata { isViewQuery: boolean; constructor(_selector: Type | string, {descendants, first, read}?: { @@ -1398,7 +1381,6 @@ export declare class ViewQueryMetadata extends QueryMetadata { first?: boolean; read?: any; }); - toString(): string; } /** @stable */