From 26ecb8c657a331137519abf137b6726043bd21dd Mon Sep 17 00:00:00 2001 From: crisbeto Date: Wed, 10 Apr 2019 20:45:59 +0200 Subject: [PATCH] refactor(form-field): explicitly set static flag on all queries Continuation of #15680. Explicitly marks all ViewChild and ContentChild queries so that the timing is consistent for apps using Ivy or ViewEngine. --- src/lib/form-field/form-field.ts | 33 ++++++++++++++++------ src/lib/select/select.spec.ts | 25 ++++++++++++++++ tools/public_api_guard/lib/form-field.d.ts | 6 +++- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index 1e59b44cc21e..edb752711e36 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -235,14 +235,31 @@ export class MatFormField extends _MatFormFieldMixinBase * @deprecated * @breaking-change 8.0.0 */ - @ViewChild('underline') underlineRef: ElementRef; - - @ViewChild('connectionContainer') _connectionContainerRef: ElementRef; - @ViewChild('inputContainer') _inputContainerRef: ElementRef; - @ViewChild('label') private _label: ElementRef; - @ContentChild(MatFormFieldControl) _control: MatFormFieldControl; - @ContentChild(MatPlaceholder) _placeholderChild: MatPlaceholder; - @ContentChild(MatLabel) _labelChild: MatLabel; + @ViewChild('underline', {static: false}) underlineRef: ElementRef; + + @ViewChild('connectionContainer', {static: true}) _connectionContainerRef: ElementRef; + @ViewChild('inputContainer', {static: false}) _inputContainerRef: ElementRef; + @ViewChild('label', {static: false}) private _label: ElementRef; + + @ContentChild(MatFormFieldControl, {static: false}) _controlNonStatic: MatFormFieldControl; + @ContentChild(MatFormFieldControl, {static: true}) _controlStatic: MatFormFieldControl; + get _control() { + // TODO(crisbeto): we need this hacky workaround in order to support both Ivy + // and ViewEngine. We should clean this up once Ivy is the default renderer. + return this._explicitFormFieldControl || this._controlNonStatic || this._controlStatic; + } + set _control(value) { + this._explicitFormFieldControl = value; + } + private _explicitFormFieldControl: MatFormFieldControl; + + @ContentChild(MatLabel, {static: false}) _labelChildNonStatic: MatLabel; + @ContentChild(MatLabel, {static: true}) _labelChildStatic: MatLabel; + get _labelChild() { + return this._labelChildNonStatic || this._labelChildStatic; + } + + @ContentChild(MatPlaceholder, {static: false}) _placeholderChild: MatPlaceholder; @ContentChildren(MatError) _errorChildren: QueryList; @ContentChildren(MatHint) _hintChildren: QueryList; @ContentChildren(MatPrefix) _prefixChildren: QueryList; diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts index 62df51a01f9a..b6c71e1c3827 100644 --- a/src/lib/select/select.spec.ts +++ b/src/lib/select/select.spec.ts @@ -2441,6 +2441,17 @@ describe('MatSelect', () => { })); }); + describe('with ngIf and mat-label', () => { + beforeEach(async(() => configureMatSelectTestingModule([SelectWithNgIfAndLabel]))); + + it('should not throw when using ngIf on a select with an associated label', fakeAsync(() => { + expect(() => { + const fixture = TestBed.createComponent(SelectWithNgIfAndLabel); + fixture.detectChanges(); + }).not.toThrow(); + })); + }); + describe('inside of a form group', () => { beforeEach(async(() => configureMatSelectTestingModule([SelectInsideFormGroup]))); @@ -4983,3 +4994,17 @@ class SelectWithoutOptionCentering { class SelectWithFormFieldLabel { placeholder: string; } + +@Component({ + template: ` + + Select something + + One + + + ` +}) +class SelectWithNgIfAndLabel { + showSelect = true; +} diff --git a/tools/public_api_guard/lib/form-field.d.ts b/tools/public_api_guard/lib/form-field.d.ts index e09103cceb25..c97a91d1bd60 100644 --- a/tools/public_api_guard/lib/form-field.d.ts +++ b/tools/public_api_guard/lib/form-field.d.ts @@ -18,12 +18,16 @@ export declare class MatFormField extends _MatFormFieldMixinBase implements Afte readonly _canLabelFloat: boolean; _connectionContainerRef: ElementRef; _control: MatFormFieldControl; + _controlNonStatic: MatFormFieldControl; + _controlStatic: MatFormFieldControl; _elementRef: ElementRef; _errorChildren: QueryList; _hintChildren: QueryList; _hintLabelId: string; _inputContainerRef: ElementRef; - _labelChild: MatLabel; + readonly _labelChild: MatLabel; + _labelChildNonStatic: MatLabel; + _labelChildStatic: MatLabel; _labelId: string; _placeholderChild: MatPlaceholder; _prefixChildren: QueryList;