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
24 changes: 20 additions & 4 deletions modules/angular2/src/core/compiler/directive_resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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 => {
Expand Down Expand Up @@ -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<string, string>): DirectiveMetadata {
host: StringMap<string, string>,
queries: StringMap<string, any>): 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({
Expand All @@ -98,6 +112,7 @@ export class DirectiveResolver {
exportAs: dm.exportAs,
moduleId: dm.moduleId,
compileChildren: dm.compileChildren,
queries: mergedQueries,
changeDetection: dm.changeDetection,
viewBindings: dm.viewBindings
});
Expand All @@ -111,7 +126,8 @@ export class DirectiveResolver {
bindings: dm.bindings,
exportAs: dm.exportAs,
moduleId: dm.moduleId,
compileChildren: dm.compileChildren
compileChildren: dm.compileChildren,
queries: mergedQueries
});
}
}
Expand Down
69 changes: 51 additions & 18 deletions modules/angular2/src/core/compiler/element_injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
} from 'angular2/src/core/change_detection/change_detection';
import {QueryList} from './query_list';
import {reflector} from 'angular2/src/core/reflection/reflection';
import {SetterFn} from 'angular2/src/core/reflection/types';
import {RenderDirectiveMetadata} from 'angular2/src/core/render/api';
import {EventConfig} from 'angular2/src/core/render/event_config';
import {PipeBinding} from '../pipes/pipe_binding';
Expand Down Expand Up @@ -138,6 +139,17 @@ export class DirectiveBinding extends ResolvedBinding {

get callOnDestroy(): boolean { return this.metadata.callOnDestroy; }

get queries(): QueryMetadataWithSetter[] {
if (isBlank(this.metadata.queries)) return [];

var res = [];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like a map to me :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StringMap does not have a map.

But semantically it is a map: stringMap -> KeyValuePair[] -> QueryMetadataWithSetter

StringMapWrapper.forEach(this.metadata.queries, (meta, fieldName) => {
var setter = reflector.setter(fieldName);
res.push(new QueryMetadataWithSetter(setter, meta));
});
return res;
}

get eventEmitters(): string[] {
return isPresent(this.metadata) && isPresent(this.metadata.events) ? this.metadata.events : [];
}
Expand All @@ -151,6 +163,7 @@ export class DirectiveBinding extends ResolvedBinding {
var rf = rb.resolvedFactories[0];
var deps = rf.dependencies.map(DirectiveDependency.createFrom);
var token = binding.token;

var metadata = RenderDirectiveMetadata.create({
id: stringify(binding.token),
type: meta instanceof ComponentMetadata ? RenderDirectiveMetadata.COMPONENT_TYPE :
Expand All @@ -161,6 +174,7 @@ export class DirectiveBinding extends ResolvedBinding {
host: isPresent(meta.host) ? MapWrapper.createFromStringMap(meta.host) : null,
properties: meta.properties,
readAttributes: DirectiveBinding._readAttributes(<any>deps),
queries: meta.queries,

callOnDestroy: hasLifecycleHook(LifecycleHooks.OnDestroy, token),
callOnChanges: hasLifecycleHook(LifecycleHooks.OnChanges, token),
Expand Down Expand Up @@ -203,6 +217,10 @@ export class PreBuiltObjects {
public elementRef: ElementRef, public templateRef: TemplateRef) {}
}

export class QueryMetadataWithSetter {
constructor(public setter: SetterFn, public metadata: QueryMetadata) {}
}

export class EventEmitterAccessor {
constructor(public eventName: string, public getter: Function) {}

Expand All @@ -214,17 +232,6 @@ export class EventEmitterAccessor {
}
}

export class HostActionAccessor {
constructor(public methodName: string, public getter: Function) {}

subscribe(view: viewModule.AppView, boundElementIndex: number, directive: Object): Object {
var eventEmitter = this.getter(directive);
return ObservableWrapper.subscribe<any[]>(
eventEmitter,
actionArgs => view.invokeElementMethod(boundElementIndex, this.methodName, actionArgs));
}
}

function _createEventEmitterAccessors(bwv: BindingWithVisibility): EventEmitterAccessor[] {
var binding = bwv.binding;
if (!(binding instanceof DirectiveBinding)) return [];
Expand Down Expand Up @@ -554,19 +561,25 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
for (var i = 0; i < deps.length; i++) {
var dep = deps[i];
if (isPresent(dep.queryDecorator)) {
this._createQueryRef(dep.queryDecorator);
this._createQueryRef(null, null, dep.queryDecorator);
}
}
}
_buildQueriesForDirective(dirIndex: number, meta: QueryMetadataWithSetter[]): void {
for (var i = 0; i < meta.length; i++) {
var m = meta[i];
this._createQueryRef(dirIndex, m.setter, m.metadata);
}
}

private _createQueryRef(query: QueryMetadata): void {
private _createQueryRef(dirIndex: number, setter: SetterFn, query: QueryMetadata): void {
var queryList = new QueryList<any>();
if (isBlank(this._query0)) {
this._query0 = new QueryRef(query, queryList, this);
this._query0 = new QueryRef(dirIndex, setter, query, queryList, this);
} else if (isBlank(this._query1)) {
this._query1 = new QueryRef(query, queryList, this);
this._query1 = new QueryRef(dirIndex, setter, query, queryList, this);
} else if (isBlank(this._query2)) {
this._query2 = new QueryRef(query, queryList, this);
this._query2 = new QueryRef(dirIndex, setter, query, queryList, this);
} else {
throw new QueryError();
}
Expand Down Expand Up @@ -758,42 +771,54 @@ class ElementInjectorInlineStrategy implements _ElementInjectorStrategy {
if (p.binding0 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding0.resolvedFactories[0].dependencies);

this._ei._buildQueriesForDirective(0, (<DirectiveBinding>p.binding0).queries);
}
if (p.binding1 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding1.resolvedFactories[0].dependencies);

this._ei._buildQueriesForDirective(1, (<DirectiveBinding>p.binding1).queries);
}
if (p.binding2 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding2.resolvedFactories[0].dependencies);
this._ei._buildQueriesForDirective(2, (<DirectiveBinding>p.binding2).queries);
}
if (p.binding3 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding3.resolvedFactories[0].dependencies);
this._ei._buildQueriesForDirective(3, (<DirectiveBinding>p.binding3).queries);
}
if (p.binding4 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding4.resolvedFactories[0].dependencies);
this._ei._buildQueriesForDirective(4, (<DirectiveBinding>p.binding4).queries);
}
if (p.binding5 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding5.resolvedFactories[0].dependencies);
this._ei._buildQueriesForDirective(5, (<DirectiveBinding>p.binding5).queries);
}
if (p.binding6 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding6.resolvedFactories[0].dependencies);
this._ei._buildQueriesForDirective(6, (<DirectiveBinding>p.binding6).queries);
}
if (p.binding7 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding7.resolvedFactories[0].dependencies);
this._ei._buildQueriesForDirective(7, (<DirectiveBinding>p.binding7).queries);
}
if (p.binding8 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding8.resolvedFactories[0].dependencies);
this._ei._buildQueriesForDirective(8, (<DirectiveBinding>p.binding8).queries);
}
if (p.binding9 instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.binding9.resolvedFactories[0].dependencies);
this._ei._buildQueriesForDirective(9, (<DirectiveBinding>p.binding9).queries);
}
}

Expand Down Expand Up @@ -896,6 +921,7 @@ class ElementInjectorDynamicStrategy implements _ElementInjectorStrategy {
if (p.bindings[i] instanceof DirectiveBinding) {
this._ei._buildQueriesForDeps(
<DirectiveDependency[]>p.bindings[i].resolvedFactory.dependencies);
this._ei._buildQueriesForDirective(i, (<DirectiveBinding>p.bindings[i]).queries);
}
}
}
Expand Down Expand Up @@ -927,15 +953,22 @@ export class QueryError extends BaseException {
}

export class QueryRef {
constructor(public query: QueryMetadata, public list: QueryList<any>,
public originator: ElementInjector, public dirty: boolean = true) {}
constructor(public dirIndex: number, public setter: SetterFn, public query: QueryMetadata,
public list: QueryList<any>, public originator: ElementInjector,
public dirty: boolean = true) {}

get isViewQuery(): boolean { return this.query.isViewQuery; }

update(): void {
if (!this.dirty) return;
this._update();
this.dirty = false;

// 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);
}
}

private _update(): void {
Expand Down
20 changes: 20 additions & 0 deletions modules/angular2/src/core/metadata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Directive extends DirectiveMetadata {
const Directive({String selector, List<String> properties,
List<String> events, Map<String, String> host,
List bindings, String exportAs, String moduleId,
Map<String, dynamic> queries,
bool compileChildren: true})
: super(
selector: selector,
Expand All @@ -26,6 +27,7 @@ class Directive extends DirectiveMetadata {
bindings: bindings,
exportAs: exportAs,
moduleId: moduleId,
queries: queries,
compileChildren: compileChildren);
}

Expand All @@ -36,6 +38,7 @@ class Component extends ComponentMetadata {
const Component({String selector, List<String> properties,
List<String> events, Map<String, String> host, bool dynamicLoadable,
List bindings, String exportAs, String moduleId,
Map<String, dynamic> queries,
bool compileChildren, List viewBindings, ChangeDetectionStrategy changeDetection})
: super(
selector: selector,
Expand All @@ -48,6 +51,7 @@ class Component extends ComponentMetadata {
moduleId: moduleId,
compileChildren: compileChildren,
viewBindings: viewBindings,
queries: queries,
changeDetection: changeDetection);
}

Expand Down Expand Up @@ -90,6 +94,14 @@ class Query extends QueryMetadata {
: super(selector, descendants: descendants);
}

/**
* See: [ContentChildrenMetadata] for docs.
*/
class ContentChildren extends ContentChildrenMetadata {
const ContentChildren(dynamic /*Type | string*/ selector, {bool descendants: false})
: super(selector, descendants: descendants);
}

/**
* See: [ViewQueryMetadata] for docs.
*/
Expand All @@ -98,6 +110,14 @@ class ViewQuery extends ViewQueryMetadata {
: super(selector, descendants: true);
}

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

/**
* See: [PropertyMetadata] for docs.
*/
Expand Down
Loading
X Tutup