From 84dd2679a93f10208c078bc0588c1fad26122633 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Thu, 23 May 2019 11:31:10 -0700 Subject: [PATCH] fix(core): require 'static' flag on queries in typings (#30639) This commit makes the static flag on @ViewChild and @ContentChild required. BREAKING CHANGE: In Angular version 8, it's required that all @ViewChild and @ContentChild queries have a 'static' flag specifying whether the query is 'static' or 'dynamic'. The compiler previously sorted queries automatically, but in 8.0 developers are required to explicitly specify which behavior is wanted. This is a temporary requirement as part of a migration; see https://angular.io/guide/static-query-migration for more details. @ViewChildren and @ContentChildren queries are always dynamic, and so are unaffected. PR Close #30639 --- .../src/app/countdown-parent.component.ts | 2 +- .../src/app/ad-banner.component.ts | 2 +- .../src/app/after-content.component.ts | 2 +- .../src/app/after-view.component.ts | 2 +- .../src/app/do-check.component.ts | 2 +- .../src/app/on-changes.component.ts | 2 +- .../src/app/hero-form.component.ts | 2 +- .../testing/src/app/shared/canvas.component.ts | 2 +- .../code/code-example.component.spec.ts | 2 +- .../code/code-tabs.component.spec.ts | 2 +- .../code/code.component.spec.ts | 2 +- aio/src/testing/doc-viewer-utils.ts | 2 +- .../dynamic-compiler/src/app.component.ts | 14 ++++++-------- .../integrationtest/src/queries.ts | 2 +- packages/compiler/src/core.ts | 2 +- packages/core/src/metadata/di.ts | 10 +++++----- .../core/test/render3/jit/directive_spec.ts | 6 ++++-- .../animations/test/animation_renderer_spec.ts | 8 ++++---- .../test/browser_animation_builder_spec.ts | 2 +- .../router/test/regression_integration.spec.ts | 5 +++-- tools/public_api_guard/core/core.d.ts | 18 +++++++++--------- 21 files changed, 46 insertions(+), 45 deletions(-) diff --git a/aio/content/examples/component-interaction/src/app/countdown-parent.component.ts b/aio/content/examples/component-interaction/src/app/countdown-parent.component.ts index 9f4e5bd4df..57f7230d89 100644 --- a/aio/content/examples/component-interaction/src/app/countdown-parent.component.ts +++ b/aio/content/examples/component-interaction/src/app/countdown-parent.component.ts @@ -39,7 +39,7 @@ export class CountdownLocalVarParentComponent { } }) export class CountdownViewChildParentComponent implements AfterViewInit { - @ViewChild(CountdownTimerComponent) + @ViewChild(CountdownTimerComponent, {static: false}) private timerComponent: CountdownTimerComponent; seconds() { return 0; } diff --git a/aio/content/examples/dynamic-component-loader/src/app/ad-banner.component.ts b/aio/content/examples/dynamic-component-loader/src/app/ad-banner.component.ts index 0bb04a8590..a802371a30 100644 --- a/aio/content/examples/dynamic-component-loader/src/app/ad-banner.component.ts +++ b/aio/content/examples/dynamic-component-loader/src/app/ad-banner.component.ts @@ -20,7 +20,7 @@ import { AdComponent } from './ad.component'; export class AdBannerComponent implements OnInit, OnDestroy { @Input() ads: AdItem[]; currentAdIndex = -1; - @ViewChild(AdDirective) adHost: AdDirective; + @ViewChild(AdDirective, {static: true}) adHost: AdDirective; interval: any; constructor(private componentFactoryResolver: ComponentFactoryResolver) { } diff --git a/aio/content/examples/lifecycle-hooks/src/app/after-content.component.ts b/aio/content/examples/lifecycle-hooks/src/app/after-content.component.ts index 36d2cff20f..858ea12c59 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/after-content.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/after-content.component.ts @@ -34,7 +34,7 @@ export class AfterContentComponent implements AfterContentChecked, AfterContentI comment = ''; // Query for a CONTENT child of type `ChildComponent` - @ContentChild(ChildComponent) contentChild: ChildComponent; + @ContentChild(ChildComponent, {static: false}) contentChild: ChildComponent; // #enddocregion hooks constructor(private logger: LoggerService) { diff --git a/aio/content/examples/lifecycle-hooks/src/app/after-view.component.ts b/aio/content/examples/lifecycle-hooks/src/app/after-view.component.ts index fd09962406..59c472b37a 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/after-view.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/after-view.component.ts @@ -35,7 +35,7 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit { private prevHero = ''; // Query for a VIEW child of type `ChildViewComponent` - @ViewChild(ChildViewComponent) viewChild: ChildViewComponent; + @ViewChild(ChildViewComponent, {static: false}) viewChild: ChildViewComponent; // #enddocregion hooks constructor(private logger: LoggerService) { diff --git a/aio/content/examples/lifecycle-hooks/src/app/do-check.component.ts b/aio/content/examples/lifecycle-hooks/src/app/do-check.component.ts index 4b8a088b9a..098ee941d2 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/do-check.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/do-check.component.ts @@ -81,7 +81,7 @@ export class DoCheckParentComponent { hero: Hero; power: string; title = 'DoCheck'; - @ViewChild(DoCheckComponent) childView: DoCheckComponent; + @ViewChild(DoCheckComponent, {static: false}) childView: DoCheckComponent; constructor() { this.reset(); } diff --git a/aio/content/examples/lifecycle-hooks/src/app/on-changes.component.ts b/aio/content/examples/lifecycle-hooks/src/app/on-changes.component.ts index 7b9cda05ef..09f3169cc2 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/on-changes.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/on-changes.component.ts @@ -55,7 +55,7 @@ export class OnChangesParentComponent { hero: Hero; power: string; title = 'OnChanges'; - @ViewChild(OnChangesComponent) childView: OnChangesComponent; + @ViewChild(OnChangesComponent, {static: false}) childView: OnChangesComponent; constructor() { this.reset(); diff --git a/aio/content/examples/template-syntax/src/app/hero-form.component.ts b/aio/content/examples/template-syntax/src/app/hero-form.component.ts index 63040131ff..173cc137de 100644 --- a/aio/content/examples/template-syntax/src/app/hero-form.component.ts +++ b/aio/content/examples/template-syntax/src/app/hero-form.component.ts @@ -13,7 +13,7 @@ import { Hero } from './hero'; }) export class HeroFormComponent { @Input() hero: Hero; - @ViewChild('heroForm') form: NgForm; + @ViewChild('heroForm', {static: false}) form: NgForm; private _submitMessage = ''; diff --git a/aio/content/examples/testing/src/app/shared/canvas.component.ts b/aio/content/examples/testing/src/app/shared/canvas.component.ts index 0f32dbeeb6..584607963e 100644 --- a/aio/content/examples/testing/src/app/shared/canvas.component.ts +++ b/aio/content/examples/testing/src/app/shared/canvas.component.ts @@ -6,7 +6,7 @@ import { Component, AfterViewInit, ViewChild } from '@angular/core'; }) export class CanvasComponent implements AfterViewInit { blobSize: number; - @ViewChild('sampleCanvas') sampleCanvas; + @ViewChild('sampleCanvas', {static: false}) sampleCanvas; constructor() { } diff --git a/aio/src/app/custom-elements/code/code-example.component.spec.ts b/aio/src/app/custom-elements/code/code-example.component.spec.ts index ace165ed76..54431dad80 100644 --- a/aio/src/app/custom-elements/code/code-example.component.spec.ts +++ b/aio/src/app/custom-elements/code/code-example.component.spec.ts @@ -96,5 +96,5 @@ class HostComponent { path = 'code-path'; hidecopy: boolean | string = false; - @ViewChild(CodeExampleComponent) codeExampleComponent: CodeExampleComponent; + @ViewChild(CodeExampleComponent, {static: true}) codeExampleComponent: CodeExampleComponent; } diff --git a/aio/src/app/custom-elements/code/code-tabs.component.spec.ts b/aio/src/app/custom-elements/code/code-tabs.component.spec.ts index 1d9dc2b36d..a7be5e8f4c 100644 --- a/aio/src/app/custom-elements/code/code-tabs.component.spec.ts +++ b/aio/src/app/custom-elements/code/code-tabs.component.spec.ts @@ -92,5 +92,5 @@ describe('CodeTabsComponent', () => { ` }) class HostComponent { - @ViewChild(CodeTabsComponent) codeTabsComponent: CodeTabsComponent; + @ViewChild(CodeTabsComponent, {static: true}) codeTabsComponent: CodeTabsComponent; } diff --git a/aio/src/app/custom-elements/code/code.component.spec.ts b/aio/src/app/custom-elements/code/code.component.spec.ts index a814754ab7..320542fbe0 100644 --- a/aio/src/app/custom-elements/code/code.component.spec.ts +++ b/aio/src/app/custom-elements/code/code.component.spec.ts @@ -284,7 +284,7 @@ class HostComponent implements AfterViewInit { region: string; header: string; - @ViewChild(CodeComponent) codeComponent: CodeComponent; + @ViewChild(CodeComponent, {static: false}) codeComponent: CodeComponent; ngAfterViewInit() { this.setCode(oneLineCode); diff --git a/aio/src/testing/doc-viewer-utils.ts b/aio/src/testing/doc-viewer-utils.ts index a078e492ec..6a3ca95137 100644 --- a/aio/src/testing/doc-viewer-utils.ts +++ b/aio/src/testing/doc-viewer-utils.ts @@ -37,7 +37,7 @@ export class TestDocViewerComponent extends DocViewerComponent { }) export class TestParentComponent { currentDoc?: DocumentContents|null; - @ViewChild(DocViewerComponent) docViewer: DocViewerComponent; + @ViewChild(DocViewerComponent, {static: true}) docViewer: DocViewerComponent; } // Mock services. diff --git a/integration/dynamic-compiler/src/app.component.ts b/integration/dynamic-compiler/src/app.component.ts index e54316da9b..16ec786eb7 100644 --- a/integration/dynamic-compiler/src/app.component.ts +++ b/integration/dynamic-compiler/src/app.component.ts @@ -10,18 +10,16 @@ declare var System: any; `, }) export class AppComponent implements AfterViewInit { - @ViewChild('vc', {read: ViewContainerRef}) container: ViewContainerRef; + @ViewChild('vc', {read: ViewContainerRef, static: false}) container: ViewContainerRef; - constructor(private compiler: Compiler) { - } + constructor(private compiler: Compiler) {} ngAfterViewInit() { System.import('./dist/lazy.bundle.js').then((module: any) => { - this.compiler.compileModuleAndAllComponentsAsync(module.LazyModule) - .then((compiled) => { - const factory = compiled.componentFactories[0]; - this.container.createComponent(factory); - }); + this.compiler.compileModuleAndAllComponentsAsync(module.LazyModule).then((compiled) => { + const factory = compiled.componentFactories[0]; + this.container.createComponent(factory); + }); }); } } diff --git a/packages/compiler-cli/integrationtest/src/queries.ts b/packages/compiler-cli/integrationtest/src/queries.ts index 8b85bfd9fa..e3d9a0840e 100644 --- a/packages/compiler-cli/integrationtest/src/queries.ts +++ b/packages/compiler-cli/integrationtest/src/queries.ts @@ -15,7 +15,7 @@ export class CompForChildQuery { @Component( {selector: 'comp-with-child-query', template: ''}) export class CompWithChildQuery { - @ViewChild(CompForChildQuery) child: CompForChildQuery; + @ViewChild(CompForChildQuery, {static: true}) child: CompForChildQuery; @ViewChildren(CompForChildQuery) children: QueryList; } diff --git a/packages/compiler/src/core.ts b/packages/compiler/src/core.ts index b3424ddfbf..18bc01d523 100644 --- a/packages/compiler/src/core.ts +++ b/packages/compiler/src/core.ts @@ -29,7 +29,7 @@ export interface Query { read: any; isViewQuery: boolean; selector: any; - static?: boolean; + static: boolean; } export const createContentChildren = makeMetadataFactory( diff --git a/packages/core/src/metadata/di.ts b/packages/core/src/metadata/di.ts index 1267296c1f..eec9b89bc6 100644 --- a/packages/core/src/metadata/di.ts +++ b/packages/core/src/metadata/di.ts @@ -102,7 +102,7 @@ export interface Query { read: any; isViewQuery: boolean; selector: any; - static?: boolean; + static: boolean; } /** @@ -218,8 +218,8 @@ export interface ContentChildDecorator { * * @Annotation */ - (selector: Type|Function|string, opts?: {read?: any, static?: boolean}): any; - new (selector: Type|Function|string, opts?: {read?: any, static?: boolean}): ContentChild; + (selector: Type|Function|string, opts: {read?: any, static: boolean}): any; + new (selector: Type|Function|string, opts: {read?: any, static: boolean}): ContentChild; } /** @@ -350,8 +350,8 @@ export interface ViewChildDecorator { * * @Annotation */ - (selector: Type|Function|string, opts?: {read?: any, static?: boolean}): any; - new (selector: Type|Function|string, opts?: {read?: any, static?: boolean}): ViewChild; + (selector: Type|Function|string, opts: {read?: any, static: boolean}): any; + new (selector: Type|Function|string, opts: {read?: any, static: boolean}): ViewChild; } /** diff --git a/packages/core/test/render3/jit/directive_spec.ts b/packages/core/test/render3/jit/directive_spec.ts index 92e214afb7..3013e05a80 100644 --- a/packages/core/test/render3/jit/directive_spec.ts +++ b/packages/core/test/render3/jit/directive_spec.ts @@ -52,7 +52,8 @@ describe('jit directive helper functions', () => { descendants: false, first: false, isViewQuery: false, - read: undefined + read: undefined, + static: false, })).toEqual({ propertyName: 'propName', predicate: ['localRef'], @@ -69,7 +70,8 @@ describe('jit directive helper functions', () => { descendants: true, first: true, isViewQuery: true, - read: undefined + read: undefined, + static: false, })).toEqual({ propertyName: 'propName', predicate: ['foo', 'bar', 'baz'], diff --git a/packages/platform-browser/animations/test/animation_renderer_spec.ts b/packages/platform-browser/animations/test/animation_renderer_spec.ts index 83f0b08d4f..67bdd84724 100644 --- a/packages/platform-browser/animations/test/animation_renderer_spec.ts +++ b/packages/platform-browser/animations/test/animation_renderer_spec.ts @@ -168,7 +168,7 @@ import {el} from '../../testing/src/browser_util'; }) class Cmp { exp: any; - @ViewChild('elm') public element: any; + @ViewChild('elm', {static: false}) public element: any; } TestBed.configureTestingModule({ @@ -213,11 +213,11 @@ import {el} from '../../testing/src/browser_util'; exp2: any = true; exp3: any = true; - @ViewChild('elm1') public elm1: any; + @ViewChild('elm1', {static: false}) public elm1: any; - @ViewChild('elm2') public elm2: any; + @ViewChild('elm2', {static: false}) public elm2: any; - @ViewChild('elm3') public elm3: any; + @ViewChild('elm3', {static: false}) public elm3: any; } TestBed.configureTestingModule({ diff --git a/packages/platform-browser/animations/test/browser_animation_builder_spec.ts b/packages/platform-browser/animations/test/browser_animation_builder_spec.ts index 38535fcda5..72cbfb10cd 100644 --- a/packages/platform-browser/animations/test/browser_animation_builder_spec.ts +++ b/packages/platform-browser/animations/test/browser_animation_builder_spec.ts @@ -51,7 +51,7 @@ import {el} from '../../testing/src/browser_util'; template: '...', }) class Cmp { - @ViewChild('target') public target: any; + @ViewChild('target', {static: false}) public target: any; constructor(public builder: AnimationBuilder) {} diff --git a/packages/router/test/regression_integration.spec.ts b/packages/router/test/regression_integration.spec.ts index 686a79b55e..e5e11d7ae3 100644 --- a/packages/router/test/regression_integration.spec.ts +++ b/packages/router/test/regression_integration.spec.ts @@ -73,9 +73,10 @@ describe('Integration', () => { }) class ComponentWithRouterLink { // TODO(issue/24571): remove '!'. - @ViewChild(TemplateRef) templateRef !: TemplateRef; + @ViewChild(TemplateRef, {static: true}) templateRef !: TemplateRef; // TODO(issue/24571): remove '!'. - @ViewChild('container', {read: ViewContainerRef}) container !: ViewContainerRef; + @ViewChild('container', {read: ViewContainerRef, static: true}) + container !: ViewContainerRef; addLink() { this.container.createEmbeddedView(this.templateRef, {$implicit: '/simple'}); diff --git a/tools/public_api_guard/core/core.d.ts b/tools/public_api_guard/core/core.d.ts index 9147efb09d..fa1423a027 100644 --- a/tools/public_api_guard/core/core.d.ts +++ b/tools/public_api_guard/core/core.d.ts @@ -168,13 +168,13 @@ export interface ConstructorSansProvider { export declare type ContentChild = Query; export interface ContentChildDecorator { - (selector: Type | Function | string, opts?: { + (selector: Type | Function | string, opts: { read?: any; - static?: boolean; + static: boolean; }): any; - new (selector: Type | Function | string, opts?: { + new (selector: Type | Function | string, opts: { read?: any; - static?: boolean; + static: boolean; }): ContentChild; } @@ -1104,7 +1104,7 @@ export interface Query { isViewQuery: boolean; read: any; selector: any; - static?: boolean; + static: boolean; } export declare abstract class Query { @@ -1382,13 +1382,13 @@ export declare const VERSION: Version; export declare type ViewChild = Query; export interface ViewChildDecorator { - (selector: Type | Function | string, opts?: { + (selector: Type | Function | string, opts: { read?: any; - static?: boolean; + static: boolean; }): any; - new (selector: Type | Function | string, opts?: { + new (selector: Type | Function | string, opts: { read?: any; - static?: boolean; + static: boolean; }): ViewChild; }