From 2e9de0b1693807b6609108bf31dc9a6f0c95d07f Mon Sep 17 00:00:00 2001 From: vsavkin Date: Thu, 17 Sep 2015 18:45:49 -0700 Subject: [PATCH] feat(core): add sugar to use ContentChildren and ViewChildren as prop decorators Closes #4237 --- .../src/core/compiler/directive_resolver.ts | 24 ++++++++++--- .../core/compiler/directive_resolver_spec.ts | 35 +++++++++++++++++-- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/modules/angular2/src/core/compiler/directive_resolver.ts b/modules/angular2/src/core/compiler/directive_resolver.ts index ff28aee63c..49819bfd08 100644 --- a/modules/angular2/src/core/compiler/directive_resolver.ts +++ b/modules/angular2/src/core/compiler/directive_resolver.ts @@ -8,7 +8,9 @@ import { PropertyMetadata, EventMetadata, HostBindingMetadata, - HostListenerMetadata + HostListenerMetadata, + ContentChildrenMetadata, + ViewChildrenMetadata } from 'angular2/src/core/metadata'; import {reflector} from 'angular2/src/core/reflection/reflection'; @@ -44,6 +46,7 @@ export class DirectiveResolver { var properties = []; var events = []; var host = {}; + var queries = {}; StringMapWrapper.forEach(propertyMetadata, (metadata: any[], propName: string) => { metadata.forEach(a => { @@ -75,17 +78,28 @@ export class DirectiveResolver { var args = isPresent(a.args) ? a.args.join(', ') : ''; host[`(${a.eventName})`] = `${propName}(${args})`; } + + if (a instanceof ContentChildrenMetadata) { + queries[propName] = a; + } + + if (a instanceof ViewChildrenMetadata) { + queries[propName] = a; + } }); }); - return this._merge(dm, properties, events, host); + return this._merge(dm, properties, events, host, queries); } private _merge(dm: DirectiveMetadata, properties: string[], events: string[], - host: StringMap): DirectiveMetadata { + host: StringMap, + queries: StringMap): DirectiveMetadata { var mergedProperties = isPresent(dm.properties) ? ListWrapper.concat(dm.properties, properties) : properties; var mergedEvents = isPresent(dm.events) ? ListWrapper.concat(dm.events, events) : events; var mergedHost = isPresent(dm.host) ? StringMapWrapper.merge(dm.host, host) : host; + var mergedQueries = + isPresent(dm.queries) ? StringMapWrapper.merge(dm.queries, queries) : queries; if (dm instanceof ComponentMetadata) { return new ComponentMetadata({ @@ -98,6 +112,7 @@ export class DirectiveResolver { exportAs: dm.exportAs, moduleId: dm.moduleId, compileChildren: dm.compileChildren, + queries: mergedQueries, changeDetection: dm.changeDetection, viewBindings: dm.viewBindings }); @@ -111,7 +126,8 @@ export class DirectiveResolver { bindings: dm.bindings, exportAs: dm.exportAs, moduleId: dm.moduleId, - compileChildren: dm.compileChildren + compileChildren: dm.compileChildren, + queries: mergedQueries }); } } diff --git a/modules/angular2/test/core/compiler/directive_resolver_spec.ts b/modules/angular2/test/core/compiler/directive_resolver_spec.ts index 4c338cd83f..f2550ba023 100644 --- a/modules/angular2/test/core/compiler/directive_resolver_spec.ts +++ b/modules/angular2/test/core/compiler/directive_resolver_spec.ts @@ -6,7 +6,11 @@ import { Property, Event, HostBinding, - HostListener + HostListener, + ContentChildren, + ContentChildrenMetadata, + ViewChildren, + ViewChildrenMetadata } from 'angular2/src/core/metadata'; @Directive({selector: 'someDirective'}) @@ -64,6 +68,17 @@ class SomeDirectiveWithHostListeners { } } +@Directive({selector: 'someDirective', queries: {"cs": new ContentChildren("c")}}) +class SomeDirectiveWithContentChildren { + @ContentChildren("a") as: any; + c; +} + +@Directive({selector: 'someDirective', queries: {"cs": new ViewChildren("c")}}) +class SomeDirectiveWithViewChildren { + @ViewChildren("a") as: any; + c; +} class SomeDirectiveWithoutMetadata {} @@ -77,7 +92,7 @@ export function main() { var directiveMetadata = resolver.resolve(SomeDirective); expect(directiveMetadata) .toEqual(new DirectiveMetadata( - {selector: 'someDirective', properties: [], events: [], host: {}})); + {selector: 'someDirective', properties: [], events: [], host: {}, queries: {}})); }); it('should throw if not matching metadata is found', () => { @@ -89,7 +104,7 @@ export function main() { var directiveMetadata = resolver.resolve(SomeChildDirective); expect(directiveMetadata) .toEqual(new DirectiveMetadata( - {selector: 'someChildDirective', properties: [], events: [], host: {}})); + {selector: 'someChildDirective', properties: [], events: [], host: {}, queries: {}})); }); describe('properties', () => { @@ -128,5 +143,19 @@ export function main() { .toEqual({'(c)': 'onC()', '(a)': 'onA()', '(b)': 'onB($event.value)'}); }); }); + + describe('queries', () => { + it('should append ContentChildren', () => { + var directiveMetadata = resolver.resolve(SomeDirectiveWithContentChildren); + expect(directiveMetadata.queries) + .toEqual({"cs": new ContentChildren("c"), "as": new ContentChildren("a")}); + }); + + it('should append ViewChildren', () => { + var directiveMetadata = resolver.resolve(SomeDirectiveWithViewChildren); + expect(directiveMetadata.queries) + .toEqual({"cs": new ViewChildren("c"), "as": new ViewChildren("a")}); + }); + }); }); }