Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 45364e5

Browse files
vicbmhevery
authored andcommitted
feat(Template): @template replaces @decorator(Directive.TRANSCLUDE_CHILDREN)
1- Transclusion syntax has changed: Before: @decorator( selector: '[ng-if]', children: Directive.TRANSCLUDE_CHILDREN, map: const {'.': 'mapping'}, <other kv pairs>) After: @template( selector: '[ng-if]', map: const {'ng-if' : 'mapping'}, <other kv pairs>) 2- Directive.children has been removed in favor of Directive.compileChildren Before: children: Directive.COMPILE_CHILDREN children: Directive.IGNORE_CHILDREN children: Directive.TRANSCLUDE_CHILDREN After: compileChildren: true compileChildren: false Use @template (see the previous section) Closes #1003
1 parent 2b33d12 commit 45364e5

28 files changed

+284
-190
lines changed

lib/application_factory.dart

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import 'dart:html';
5151
metaTargets: const [
5252
Injectable,
5353
Decorator,
54+
Template,
5455
Controller,
5556
Component,
5657
Formatter

lib/core/annotation.dart

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export "package:angular/core/annotation_src.dart" show
1717
Component,
1818
Controller,
1919
Decorator,
20+
Template,
2021

2122
DirectiveAnnotation,
2223
NgAttr,

lib/core/annotation_src.dart

+58-37
Original file line numberDiff line numberDiff line change
@@ -68,30 +68,11 @@ abstract class Directive {
6868
* Specifies the compiler action to be taken on the child nodes of the
6969
* element which this currently being compiled. The values are:
7070
*
71-
* * [COMPILE_CHILDREN] (*default*)
72-
* * [TRANSCLUDE_CHILDREN]
73-
* * [IGNORE_CHILDREN]
71+
* * [:true:] Compile the child nodes of the element. (default)
72+
* * [:false:] Do not compile/visit the child nodes. Angular markup on
73+
* descendant nodes will not be processed.
7474
*/
75-
@deprecated
76-
final String children;
77-
78-
/**
79-
* Compile the child nodes of the element. This is the default.
80-
*/
81-
@deprecated
82-
static const String COMPILE_CHILDREN = 'compile';
83-
/**
84-
* Compile the child nodes for transclusion and makes available
85-
* [BoundViewFactory], [ViewFactory] and [ViewPort] for injection.
86-
*/
87-
@deprecated
88-
static const String TRANSCLUDE_CHILDREN = 'transclude';
89-
/**
90-
* Do not compile/visit the child nodes. Angular markup on descendant nodes
91-
* will not be processed.
92-
*/
93-
@deprecated
94-
static const String IGNORE_CHILDREN = 'ignore';
75+
final bool compileChildren;
9576

9677
/**
9778
* A directive/component controller class can be injected into other
@@ -214,18 +195,19 @@ abstract class Directive {
214195

215196
const Directive({
216197
this.selector,
217-
this.children: Directive.COMPILE_CHILDREN,
198+
this.compileChildren: true,
218199
this.visibility: Directive.LOCAL_VISIBILITY,
219200
this.module,
220201
this.map: const {},
221202
this.exportExpressions: const [],
222203
this.exportExpressionAttrs: const []
223204
});
224205

225-
toString() => selector;
226-
get hashCode => selector.hashCode;
227-
operator==(other) =>
228-
other is Directive && selector == other.selector;
206+
String toString() => selector;
207+
208+
int get hashCode => selector.hashCode;
209+
210+
bool operator==(other) => other is Directive && selector == other.selector;
229211

230212
Directive _cloneWithNewMap(newMap);
231213
}
@@ -332,7 +314,7 @@ class Component extends Directive {
332314
_applyAuthorStyles = applyAuthorStyles,
333315
_resetStyleInheritance = resetStyleInheritance,
334316
super(selector: selector,
335-
children: Directive.COMPILE_CHILDREN,
317+
compileChildren: true,
336318
visibility: visibility,
337319
map: map,
338320
module: module,
@@ -343,7 +325,7 @@ class Component extends Directive {
343325
const [] :
344326
_cssUrls is List ? _cssUrls : [_cssUrls];
345327

346-
Directive _cloneWithNewMap(newMap) =>
328+
Component _cloneWithNewMap(newMap) =>
347329
new Component(
348330
template: template,
349331
templateUrl: templateUrl,
@@ -374,24 +356,24 @@ class Component extends Directive {
374356
* * `detach()` - Called on when owning scope is destroyed.
375357
*/
376358
class Decorator extends Directive {
377-
const Decorator({children: Directive.COMPILE_CHILDREN,
359+
const Decorator({compileChildren: true,
378360
map,
379361
selector,
380362
module,
381363
visibility,
382364
exportExpressions,
383365
exportExpressionAttrs})
384366
: super(selector: selector,
385-
children: children,
367+
compileChildren: compileChildren,
386368
visibility: visibility,
387369
map: map,
388370
module: module,
389371
exportExpressions: exportExpressions,
390372
exportExpressionAttrs: exportExpressionAttrs);
391373

392-
Directive _cloneWithNewMap(newMap) =>
374+
Decorator _cloneWithNewMap(newMap) =>
393375
new Decorator(
394-
children: children,
376+
compileChildren: compileChildren,
395377
map: newMap,
396378
module: module,
397379
selector: selector,
@@ -400,6 +382,45 @@ class Decorator extends Directive {
400382
exportExpressionAttrs: exportExpressionAttrs);
401383
}
402384

385+
386+
387+
/**
388+
* Meta-data marker placed on a class which should act as template.
389+
*
390+
* Angular templates are instantiated using dependency injection, and can
391+
* ask for any injectable object in their constructor. Templates can also ask
392+
* for other components or directives declared on the DOM element.
393+
*
394+
* Templates can implement [NgAttachAware], [NgDetachAware] and declare these
395+
* optional methods:
396+
*
397+
* * `attach()` - Called on first [Scope.apply()].
398+
* * `detach()` - Called on when owning scope is destroyed.
399+
*/
400+
class Template extends Directive {
401+
const Template({map,
402+
selector,
403+
module,
404+
visibility,
405+
exportExpressions,
406+
exportExpressionAttrs})
407+
: super(selector: selector,
408+
compileChildren: true,
409+
visibility: visibility,
410+
map: map,
411+
module: module,
412+
exportExpressions: exportExpressions,
413+
exportExpressionAttrs: exportExpressionAttrs);
414+
415+
Template _cloneWithNewMap(newMap) =>
416+
new Template(map: newMap,
417+
module: module,
418+
selector: selector,
419+
visibility: visibility,
420+
exportExpressions: exportExpressions,
421+
exportExpressionAttrs: exportExpressionAttrs);
422+
}
423+
403424
/**
404425
* Meta-data marker placed on a class which should act as a controller for your
405426
* application.
@@ -427,7 +448,7 @@ class Controller extends Decorator {
427448
final String publishAs;
428449

429450
const Controller({
430-
children: Directive.COMPILE_CHILDREN,
451+
compileChildren: true,
431452
this.publishAs,
432453
map,
433454
module,
@@ -437,7 +458,7 @@ class Controller extends Decorator {
437458
exportExpressionAttrs
438459
})
439460
: super(selector: selector,
440-
children: children,
461+
compileChildren: compileChildren,
441462
visibility: visibility,
442463
map: map,
443464
module: module,
@@ -446,7 +467,7 @@ class Controller extends Decorator {
446467

447468
Directive _cloneWithNewMap(newMap) =>
448469
new Controller(
449-
children: children,
470+
compileChildren: compileChildren,
450471
publishAs: publishAs,
451472
module: module,
452473
map: newMap,

lib/core/registry_dynamic.dart

+24-29
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import 'package:angular/core/registry.dart';
77
export 'package:angular/core/registry.dart' show
88
MetadataExtractor;
99

10-
var _fieldMetadataCache = new Map<Type, Map<String, DirectiveAnnotation>>();
11-
1210
class DynamicMetadataExtractor implements MetadataExtractor {
11+
static final _fieldMetadataCache = <Type, Map<String, DirectiveAnnotation>>{};
12+
1313
final _fieldAnnotations = [
1414
reflectType(NgAttr),
1515
reflectType(NgOneWay),
@@ -24,29 +24,28 @@ class DynamicMetadataExtractor implements MetadataExtractor {
2424
if (metadata == null) {
2525
metadata = [];
2626
} else {
27-
metadata = metadata.map((InstanceMirror im) => map(type, im.reflectee));
27+
metadata = metadata.map((InstanceMirror im) => _mergeMap(type, im.reflectee));
2828
}
2929
return metadata;
3030
}
3131

32-
map(Type type, obj) {
33-
if (obj is Directive) {
34-
return mapDirectiveAnnotation(type, obj);
35-
} else {
36-
return obj;
37-
}
38-
}
39-
40-
Directive mapDirectiveAnnotation(Type type, Directive annotation) {
41-
var match;
42-
var fieldMetadata = fieldMetadataExtractor(type);
43-
if (fieldMetadata.isNotEmpty) {
44-
var newMap = annotation.map == null ? {} : new Map.from(annotation.map);
45-
fieldMetadata.forEach((String fieldName, DirectiveAnnotation ann) {
32+
/**
33+
* Merges the field annotations with the [AbstractNgAttrAnnotation.map]
34+
* definition from the [Directive].
35+
*
36+
* [_mergeDirectiveMap] throws when the definition for an annotated is
37+
* duplicated in the [AbstractNgAttrAnnotation.map]
38+
*/
39+
dynamic _mergeMap(Type type, annotation) {
40+
if (annotation is! Directive) return annotation;
41+
var metaData = _extractFieldMetadata(type);
42+
if (metaData.isNotEmpty) {
43+
var newMap = annotation.map == null ? <String, String>{} : new Map.from(annotation.map);
44+
metaData.forEach((String fieldName, DirectiveAnnotation ann) {
4645
var attrName = ann.attrName;
4746
if (newMap.containsKey(attrName)) {
4847
throw 'Mapping for attribute $attrName is already defined (while '
49-
'processing annottation for field $fieldName of $type)';
48+
'processing annotation for field $fieldName of $type)';
5049
}
5150
newMap[attrName] = '${mappingSpec(ann)}$fieldName';
5251
});
@@ -55,21 +54,17 @@ class DynamicMetadataExtractor implements MetadataExtractor {
5554
return annotation;
5655
}
5756

58-
59-
Map<String, DirectiveAnnotation> fieldMetadataExtractor(Type type) =>
57+
Map<String, DirectiveAnnotation> _extractFieldMetadata(Type type) =>
6058
_fieldMetadataCache.putIfAbsent(type, () => _fieldMetadataExtractor(reflectType(type)));
6159

60+
/// Extract metadata defined on fields via a [DirectiveAnnotation]
6261
Map<String, DirectiveAnnotation> _fieldMetadataExtractor(ClassMirror cm) {
6362
var fields = <String, DirectiveAnnotation>{};
64-
if(cm.superclass != null) {
65-
fields.addAll(_fieldMetadataExtractor(cm.superclass));
66-
} else {
67-
fields = {};
68-
}
63+
if(cm.superclass != null) fields.addAll(_fieldMetadataExtractor(cm.superclass));
64+
6965
Map<Symbol, DeclarationMirror> declarations = cm.declarations;
70-
declarations.forEach((symbol, dm) {
71-
if(dm is VariableMirror ||
72-
dm is MethodMirror && (dm.isGetter || dm.isSetter)) {
66+
declarations.forEach((Symbol symbol, DeclarationMirror dm) {
67+
if (dm is VariableMirror || dm is MethodMirror && (dm.isGetter || dm.isSetter)) {
7368
var fieldName = MirrorSystem.getName(symbol);
7469
if (dm is MethodMirror && dm.isSetter) {
7570
// Remove "=" from the end of the setter.
@@ -79,7 +74,7 @@ class DynamicMetadataExtractor implements MetadataExtractor {
7974
if (_fieldAnnotations.contains(meta.type)) {
8075
if (fields.containsKey(fieldName)) {
8176
throw 'Attribute annotation for $fieldName is defined more '
82-
'than once in ${cm.reflectedType}';
77+
'than once in ${cm.reflectedType}';
8378
}
8479
fields[fieldName] = meta.reflectee as DirectiveAnnotation;
8580
}

lib/core_dom/common.dart

+12-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,18 @@ class DirectiveRef {
1818
final Directive annotation;
1919
final String value;
2020
final mappings = new List<MappingParts>();
21-
22-
DirectiveRef(this.element, this.type, this.annotation, [ this.value ]);
21+
Map<String, String> _templateAttrs;
22+
Map<String, String> get templateAttrs => _templateAttrs;
23+
24+
DirectiveRef(this.element, this.type, this.annotation, [ this.value ]) {
25+
if (annotation is Template && annotation.map != null) {
26+
var attributes = (element as dom.Element).attributes;
27+
_templateAttrs = <String, String>{};
28+
annotation.map.keys.forEach((attrName) {
29+
_templateAttrs[attrName] = attributes[attrName];
30+
});
31+
}
32+
}
2333

2434
String toString() {
2535
var html = element is dom.Element

0 commit comments

Comments
 (0)