X Tutup
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions modules/angular2/src/core/compiler/directive_resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import {
HostBindingMetadata,
HostListenerMetadata,
ContentChildrenMetadata,
ViewChildrenMetadata
ViewChildrenMetadata,
ContentChildMetadata,
ViewChildMetadata
} from 'angular2/src/core/metadata';
import {reflector} from 'angular2/src/core/reflection/reflection';

/**
/*
* Resolve a `Type` for {@link DirectiveMetadata}.
*
* This interface can be overridden by the application developer to create custom behavior.
Expand Down Expand Up @@ -86,6 +88,14 @@ export class DirectiveResolver {
if (a instanceof ViewChildrenMetadata) {
queries[propName] = a;
}

if (a instanceof ContentChildMetadata) {
queries[propName] = a;
}

if (a instanceof ViewChildMetadata) {
queries[propName] = a;
}
});
});
return this._merge(dm, properties, events, host, queries);
Expand Down
6 changes: 5 additions & 1 deletion modules/angular2/src/core/compiler/element_injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,11 @@ export class QueryRef {
// TODO delete the check once only field queries are supported
if (isPresent(this.dirIndex)) {
var dir = this.originator.getDirectiveAtIndex(this.dirIndex);
this.setter(dir, this.list);
if (this.query.first) {
this.setter(dir, this.list.length > 0 ? this.list.first : null);
} else {
this.setter(dir, this.list);
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions modules/angular2/src/core/metadata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ class ContentChildren extends ContentChildrenMetadata {
: super(selector, descendants: descendants);
}

/**
* See: [ContentChildMetadata] for docs.
*/
class ContentChild extends ContentChildMetadata {
const ContentChild(dynamic /*Type | string*/ selector)
: super(selector);
}

/**
* See: [ViewQueryMetadata] for docs.
*/
Expand All @@ -118,6 +126,14 @@ class ViewChildren extends ViewChildrenMetadata {
: super(selector);
}

/**
* See: [ViewChildMetadata] for docs.
*/
class ViewChild extends ViewChildMetadata {
const ViewChild(dynamic /*Type | string*/ selector)
: super(selector);
}

/**
* See: [PropertyMetadata] for docs.
*/
Expand Down
31 changes: 28 additions & 3 deletions modules/angular2/src/core/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
export {
QueryMetadata,
ContentChildrenMetadata,
ContentChildMetadata,
ViewChildrenMetadata,
ViewQueryMetadata,
AttributeMetadata,
ViewChildMetadata,
AttributeMetadata
} from './metadata/di';

export {
Expand All @@ -26,9 +28,11 @@ export {ViewMetadata, ViewEncapsulation} from './metadata/view';
import {
QueryMetadata,
ContentChildrenMetadata,
ContentChildMetadata,
ViewChildrenMetadata,
ViewChildMetadata,
ViewQueryMetadata,
AttributeMetadata,
AttributeMetadata
} from './metadata/di';

import {
Expand Down Expand Up @@ -408,11 +412,22 @@ export interface ContentChildrenFactory {
new (selector: Type | string, {descendants}?: {descendants?: boolean}): ContentChildrenMetadata;
}

export interface ContentChildFactory {
(selector: Type | string): any;
new (selector: Type | string): ContentChildFactory;
}

export interface ViewChildrenFactory {
(selector: Type | string): any;
new (selector: Type | string): ViewChildrenMetadata;
}

export interface ViewChildFactory {
(selector: Type | string): any;
new (selector: Type | string): ViewChildFactory;
}


/**
* {@link PipeMetadata} factory for creating decorators.
*
Expand Down Expand Up @@ -546,13 +561,23 @@ export var Query: QueryFactory = makeParamDecorator(QueryMetadata);
*/
export var ContentChildren: ContentChildrenFactory = makePropDecorator(ContentChildrenMetadata);

/**
* {@link ContentChildMetadata} factory function.
*/
export var ContentChild: ContentChildFactory = makePropDecorator(ContentChildMetadata);

/**
* {@link ViewChildrenMetadata} factory function.
*/
export var ViewChildren: ViewChildrenFactory = makePropDecorator(ViewChildrenMetadata);

/**
* {@link ViewQueryMetadata} factory function.
* {@link ViewChildMetadata} factory function.
*/
export var ViewChild: ViewChildFactory = makePropDecorator(ViewChildMetadata);

/**
* {@link di/ViewQueryMetadata} factory function.
*/
export var ViewQuery: QueryFactory = makeParamDecorator(ViewQueryMetadata);

Expand Down
61 changes: 58 additions & 3 deletions modules/angular2/src/core/metadata/di.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,13 @@ export class QueryMetadata extends DependencyMetadata {
* children (true).
*/
descendants: boolean;
first: boolean;

constructor(private _selector: Type | string,
{descendants = false}: {descendants?: boolean} = {}) {
{descendants = false, first = false}: {descendants?: boolean, first?: boolean} = {}) {
super();
this.descendants = descendants;
this.first = first;
}

/**
Expand Down Expand Up @@ -229,6 +231,32 @@ export class ContentChildrenMetadata extends QueryMetadata {
}
}

// TODO: add an example after ContentChild and ViewChild are in master
/**
* Configures a content query.
*
* Content queries are set before the `afterContentInit` callback is called.
*
* ### Example
*
* ```
* @Directive({
* selector: 'someDir'
* })
* class SomeDir {
* @ContentChild(ChildDirective) contentChild;
*
* afterContentInit() {
* // contentChild is set
* }
* }
* ```
*/
@CONST()
export class ContentChildMetadata extends QueryMetadata {
constructor(_selector: Type | string) { super(_selector, {descendants: true, first: true}); }
}

/**
* Similar to {@link QueryMetadata}, but querying the component view, instead of
* the content children.
Expand Down Expand Up @@ -266,8 +294,9 @@ export class ContentChildrenMetadata extends QueryMetadata {
*/
@CONST()
export class ViewQueryMetadata extends QueryMetadata {
constructor(_selector: Type | string, {descendants = false}: {descendants?: boolean} = {}) {
super(_selector, {descendants: descendants});
constructor(_selector: Type | string,
{descendants = false, first = false}: {descendants?: boolean, first?: boolean} = {}) {
super(_selector, {descendants: descendants, first: first});
}

/**
Expand Down Expand Up @@ -302,3 +331,29 @@ export class ViewQueryMetadata extends QueryMetadata {
export class ViewChildrenMetadata extends ViewQueryMetadata {
constructor(_selector: Type | string) { super(_selector, {descendants: true}); }
}

/**
* Configures a view query.
*
* View queries are set before the `afterViewInit` callback is called.
*
* ### Example
*
* ```
* @Component({
* selector: 'someDir'
* })
* @View({templateUrl: 'someTemplate', directives: [ItemDirective]})
* class SomeDir {
* @ViewChild(ItemDirective) viewChild:ItemDirective;
*
* afterViewInit() {
* // viewChild is set
* }
* }
* ```
*/
@CONST()
export class ViewChildMetadata extends ViewQueryMetadata {
constructor(_selector: Type | string) { super(_selector, {descendants: true, first: true}); }
}
30 changes: 29 additions & 1 deletion modules/angular2/test/core/compiler/directive_resolver_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import {
ContentChildren,
ContentChildrenMetadata,
ViewChildren,
ViewChildrenMetadata
ViewChildrenMetadata,
ContentChild,
ContentChildMetadata,
ViewChild,
ViewChildMetadata
} from 'angular2/src/core/metadata';

@Directive({selector: 'someDirective'})
Expand Down Expand Up @@ -80,6 +84,18 @@ class SomeDirectiveWithViewChildren {
c;
}

@Directive({selector: 'someDirective', queries: {"c": new ContentChild("c")}})
class SomeDirectiveWithContentChild {
@ContentChild("a") a: any;
c;
}

@Directive({selector: 'someDirective', queries: {"c": new ViewChild("c")}})
class SomeDirectiveWithViewChild {
@ViewChild("a") a: any;
c;
}

class SomeDirectiveWithoutMetadata {}

export function main() {
Expand Down Expand Up @@ -156,6 +172,18 @@ export function main() {
expect(directiveMetadata.queries)
.toEqual({"cs": new ViewChildren("c"), "as": new ViewChildren("a")});
});

it('should append ContentChild', () => {
var directiveMetadata = resolver.resolve(SomeDirectiveWithContentChild);
expect(directiveMetadata.queries)
.toEqual({"c": new ContentChild("c"), "a": new ContentChild("a")});
});

it('should append ViewChild', () => {
var directiveMetadata = resolver.resolve(SomeDirectiveWithViewChild);
expect(directiveMetadata.queries)
.toEqual({"c": new ViewChild("c"), "a": new ViewChild("a")});
});
});
});
}
Loading
X Tutup