feat(ivy): compile queries in ngtsc (#24862)
This commit adds support for @ContentChild[ren] and @ViewChild[ren] in ngtsc. Previously queries were ignored. PR Close #24862
This commit is contained in:

committed by
Victor Berchet

parent
6eb6ac7c12
commit
76f8f78920
@ -6,7 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
type FnWithArg<T> = (arg?: any) => T;
|
||||
interface FnWithArg<T> {
|
||||
(...args: any[]): T;
|
||||
new (...args: any[]): T;
|
||||
}
|
||||
|
||||
function callableClassDecorator(): FnWithArg<(clazz: any) => any> {
|
||||
return null !;
|
||||
@ -16,6 +19,10 @@ function callableParamDecorator(): FnWithArg<(a: any, b: any, c: any) => void> {
|
||||
return null !;
|
||||
}
|
||||
|
||||
function callablePropDecorator(): FnWithArg<(a: any, b: any) => any> {
|
||||
return null !;
|
||||
}
|
||||
|
||||
export const Component = callableClassDecorator();
|
||||
export const Directive = callableClassDecorator();
|
||||
export const Injectable = callableClassDecorator();
|
||||
@ -27,6 +34,12 @@ export const Inject = callableParamDecorator();
|
||||
export const Self = callableParamDecorator();
|
||||
export const SkipSelf = callableParamDecorator();
|
||||
export const Optional = callableParamDecorator();
|
||||
|
||||
export const ContentChild = callablePropDecorator();
|
||||
export const ContentChildren = callablePropDecorator();
|
||||
export const ViewChild = callablePropDecorator();
|
||||
export const ViewChildren = callablePropDecorator();
|
||||
|
||||
export type ModuleWithProviders<T> = any;
|
||||
|
||||
export class ChangeDetectorRef {}
|
||||
|
@ -412,4 +412,36 @@ describe('ngtsc behavioral tests', () => {
|
||||
.toContain(
|
||||
`factory: function FooCmp_Factory() { return new FooCmp(i0.ɵinjectAttribute("test"), i0.ɵinjectChangeDetectorRef(), i0.ɵinjectElementRef(), i0.ɵdirectiveInject(i0.INJECTOR), i0.ɵinjectTemplateRef(), i0.ɵinjectViewContainerRef()); }`);
|
||||
});
|
||||
|
||||
it('should generate queries for components', () => {
|
||||
writeConfig();
|
||||
write(`test.ts`, `
|
||||
import {Component, ContentChild, ContentChildren, TemplateRef, ViewChild} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'test',
|
||||
template: '<div #foo></div>',
|
||||
queries: {
|
||||
'mview': new ViewChild('test1'),
|
||||
'mcontent': new ContentChild('test2'),
|
||||
}
|
||||
})
|
||||
class FooCmp {
|
||||
@ContentChild('bar', {read: TemplateRef}) child: any;
|
||||
@ContentChildren(TemplateRef) children: any;
|
||||
get aview(): any { return null; }
|
||||
@ViewChild('accessor') set aview(value: any) {}
|
||||
}
|
||||
`);
|
||||
|
||||
const exitCode = main(['-p', basePath], errorSpy);
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
expect(exitCode).toBe(0);
|
||||
const jsContents = getContents('test.js');
|
||||
expect(jsContents).toContain(`i0.ɵQ(null, ["bar"], true, TemplateRef)`);
|
||||
expect(jsContents).toContain(`i0.ɵQ(null, TemplateRef, false)`);
|
||||
expect(jsContents).toContain(`i0.ɵQ(null, ["test2"], true)`);
|
||||
expect(jsContents).toContain(`i0.ɵQ(0, ["accessor"], true)`);
|
||||
expect(jsContents).toContain(`i0.ɵQ(1, ["test1"], true)`);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user