fix(ivy): throw if @Input and @ContentChild share a property (#28415)
In View Engine, we supported @Input and @ContentChild annotations on the same property. This feature was somewhat brittle because it would only work for static queries, so it would break if a content child was passed in wrapped in an *ngIf. Due to the inconsistent behavior and low usage both internally and externally, we will likely be deprecating it in the next version, and it does not make sense to perpetuate it in Ivy. This commit ensures that we now throw in Ivy if we encounter the two annotations on the same property. PR Close #28415
This commit is contained in:

committed by
Jason Aden

parent
7d9aa67d8c
commit
fdc6e159b4
@ -6,13 +6,13 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, ApplicationRef, Component, ComponentRef, ContentChild, Directive, ErrorHandler, EventEmitter, HostListener, InjectionToken, Injector, Input, NgModule, NgModuleRef, NgZone, Output, Pipe, PipeTransform, Provider, QueryList, Renderer2, SimpleChanges, TemplateRef, ViewChildren, ViewContainerRef, destroyPlatform, ɵivyEnabled as ivyEnabled} from '@angular/core';
|
||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, ApplicationRef, Component, ComponentRef, ContentChild, Directive, ErrorHandler, EventEmitter, HostListener, InjectionToken, Injector, Input, NgModule, NgModuleRef, NgZone, Output, Pipe, PipeTransform, Provider, QueryList, Renderer2, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, destroyPlatform, ɵivyEnabled as ivyEnabled} from '@angular/core';
|
||||
import {TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
|
||||
import {BrowserModule, By, DOCUMENT} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
import {fixmeIvy, modifiedInIvy} from '@angular/private/testing';
|
||||
import {fixmeIvy, modifiedInIvy, onlyInIvy} from '@angular/private/testing';
|
||||
|
||||
if (ivyEnabled) {
|
||||
describe('ivy', () => { declareTests(); });
|
||||
@ -355,7 +355,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||
});
|
||||
});
|
||||
|
||||
fixmeIvy('FW-797: @ContentChildren results are assigned after @Input bindings')
|
||||
modifiedInIvy('Static ViewChild and ContentChild queries are resolved in update mode')
|
||||
.it('should support @ContentChild and @Input on the same property for static queries',
|
||||
() => {
|
||||
@Directive({selector: 'test'})
|
||||
@ -387,6 +387,22 @@ function declareTests(config?: {useJit: boolean}) {
|
||||
expect(testDirs[2].tpl).toBeDefined();
|
||||
});
|
||||
|
||||
onlyInIvy('Ivy does not support @ContentChild and @Input on the same property')
|
||||
.it('should throw if @ContentChild and @Input are on the same property', () => {
|
||||
@Directive({selector: 'test'})
|
||||
class Test {
|
||||
@Input() @ContentChild(TemplateRef) tpl !: TemplateRef<any>;
|
||||
}
|
||||
|
||||
@Component({selector: 'my-app', template: `<test></test>`})
|
||||
class App {
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App);
|
||||
}).toThrowError(/Cannot combine @Input decorators with query decorators/);
|
||||
});
|
||||
|
||||
it('should not add ng-version for dynamically created components', () => {
|
||||
@Component({template: ''})
|
||||
class App {
|
||||
|
Reference in New Issue
Block a user