Skip to content

Commit ed858d6

Browse files
0bffd18 feat(NgTemplateOutlet): add NgTemplateOutlet directive
1 parent 9792ba7 commit ed858d6

10 files changed

Lines changed: 654 additions & 505 deletions

File tree

BUILD_INFO

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Wed Apr 20 04:20:16 UTC 2016
2-
fb88216de80fb9d443a94fd4a00be3979617e72b
1+
Wed Apr 20 04:20:47 UTC 2016
2+
0bffd18d05414680841a266be7b441f802936997

_analyzer.dart

Lines changed: 500 additions & 498 deletions
Large diffs are not rendered by default.

lib/src/common/directives.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ library angular2.src.common.directives;
88
export "directives/ng_class.dart" show NgClass;
99
export "directives/ng_for.dart" show NgFor;
1010
export "directives/ng_if.dart" show NgIf;
11+
export "directives/ng_template_outlet.dart" show NgTemplateOutlet;
1112
export "directives/ng_style.dart" show NgStyle;
1213
export "directives/ng_switch.dart" show NgSwitch, NgSwitchWhen, NgSwitchDefault;
1314
export "directives/ng_plural.dart" show NgPlural, NgPluralCase, NgLocalization;

lib/src/common/directives/core_directives.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import "package:angular2/src/facade/lang.dart" show Type;
44
import "ng_class.dart" show NgClass;
55
import "ng_for.dart" show NgFor;
66
import "ng_if.dart" show NgIf;
7+
import "ng_template_outlet.dart" show NgTemplateOutlet;
78
import "ng_style.dart" show NgStyle;
89
import "ng_switch.dart" show NgSwitch, NgSwitchWhen, NgSwitchDefault;
910
import "ng_plural.dart" show NgPlural, NgPluralCase;
@@ -52,6 +53,7 @@ const List<Type> CORE_DIRECTIVES = const [
5253
NgClass,
5354
NgFor,
5455
NgIf,
56+
NgTemplateOutlet,
5557
NgStyle,
5658
NgSwitch,
5759
NgSwitchWhen,

lib/src/common/directives/ng_for.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import "../../facade/exceptions.dart" show BaseException;
2222
* each instantiated template inherits from the outer context with the given loop variable set
2323
* to the current item from the iterable.
2424
*
25-
* ### Local Variables
25+
* # Local Variables
2626
*
2727
* `NgFor` provides several exported values that can be aliased to local variables:
2828
*
@@ -34,7 +34,7 @@ import "../../facade/exceptions.dart" show BaseException;
3434
* * `even` will be set to a boolean value indicating whether this item has an even index.
3535
* * `odd` will be set to a boolean value indicating whether this item has an odd index.
3636
*
37-
* ### Change Propagation
37+
* # Change Propagation
3838
*
3939
* When the contents of the iterator changes, `NgFor` makes the corresponding changes to the DOM:
4040
*
@@ -57,7 +57,7 @@ import "../../facade/exceptions.dart" show BaseException;
5757
* elements were deleted and all new elements inserted). This is an expensive operation and should
5858
* be avoided if possible.
5959
*
60-
* ### Syntax
60+
* # Syntax
6161
*
6262
* - `<li *ngFor="#item of items; #i = index">...</li>`
6363
* - `<li template="ngFor #item of items; #i = index">...</li>`

lib/src/common/directives/ng_switch.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class SwitchView {
2929
* `NgSwitch` simply inserts nested elements based on which match expression matches the value
3030
* obtained from the evaluated switch expression. In other words, you define a container element
3131
* (where you place the directive with a switch expression on the
32-
* `[ngSwitch]="..."` attribute), define any inner elements inside of the directive and
32+
* **`[ngSwitch]="..."` attribute**), define any inner elements inside of the directive and
3333
* place a `[ngSwitchWhen]` attribute per element.
3434
*
3535
* The `ngSwitchWhen` property is used to inform `NgSwitch` which element to display when the
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
library angular2.src.common.directives.ng_template_outlet;
2+
3+
import "package:angular2/core.dart"
4+
show Directive, Input, ViewContainerRef, ViewRef, TemplateRef;
5+
import "package:angular2/src/facade/lang.dart" show isPresent;
6+
7+
/**
8+
* Creates and inserts an embedded view based on a prepared `TemplateRef`.
9+
*
10+
* ### Syntax
11+
* - `<template [ngTemplateOutlet]="templateRefExpression"></template>`
12+
*/
13+
@Directive(selector: "[ngTemplateOutlet]")
14+
class NgTemplateOutlet {
15+
ViewContainerRef _viewContainerRef;
16+
ViewRef _insertedViewRef;
17+
NgTemplateOutlet(this._viewContainerRef) {}
18+
@Input()
19+
set ngTemplateOutlet(TemplateRef templateRef) {
20+
if (isPresent(this._insertedViewRef)) {
21+
this
22+
._viewContainerRef
23+
.remove(this._viewContainerRef.indexOf(this._insertedViewRef));
24+
}
25+
if (isPresent(templateRef)) {
26+
this._insertedViewRef =
27+
this._viewContainerRef.createEmbeddedView(templateRef);
28+
}
29+
}
30+
}

lib/src/common/forms/directives/ng_form_control.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const formControlBinding =
5959
* }
6060
* ```
6161
*
62-
* ### ngModel
62+
* ###ngModel
6363
*
6464
* We can also use `ngModel` to bind a domain model to the form.
6565
*
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
library angular2.test.common.directives.ng_template_outlet_spec;
2+
3+
import "package:angular2/testing_internal.dart"
4+
show
5+
AsyncTestCompleter,
6+
TestComponentBuilder,
7+
beforeEach,
8+
ddescribe,
9+
describe,
10+
el,
11+
expect,
12+
iit,
13+
inject,
14+
it,
15+
xit;
16+
import "package:angular2/core.dart"
17+
show Component, Directive, TemplateRef, ContentChildren, QueryList;
18+
import "package:angular2/src/common/directives/ng_template_outlet.dart"
19+
show NgTemplateOutlet;
20+
21+
main() {
22+
describe("insert", () {
23+
it(
24+
"should do nothing if templateRef is null",
25+
inject([TestComponentBuilder, AsyncTestCompleter],
26+
(TestComponentBuilder tcb, async) {
27+
var template = '''<template [ngTemplateOutlet]="null"></template>''';
28+
tcb
29+
.overrideTemplate(TestComponent, template)
30+
.createAsync(TestComponent)
31+
.then((fixture) {
32+
fixture.detectChanges();
33+
expect(fixture.nativeElement).toHaveText("");
34+
async.done();
35+
});
36+
}));
37+
it(
38+
"should insert content specified by TemplateRef",
39+
inject([TestComponentBuilder, AsyncTestCompleter],
40+
(TestComponentBuilder tcb, async) {
41+
var template =
42+
'''<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>''';
43+
tcb
44+
.overrideTemplate(TestComponent, template)
45+
.createAsync(TestComponent)
46+
.then((fixture) {
47+
fixture.detectChanges();
48+
expect(fixture.nativeElement).toHaveText("");
49+
var refs = fixture.debugElement.children[0].getLocal("refs");
50+
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
51+
fixture.detectChanges();
52+
expect(fixture.nativeElement).toHaveText("foo");
53+
async.done();
54+
});
55+
}));
56+
it(
57+
"should clear content if TemplateRef becomes null",
58+
inject([TestComponentBuilder, AsyncTestCompleter],
59+
(TestComponentBuilder tcb, async) {
60+
var template =
61+
'''<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>''';
62+
tcb
63+
.overrideTemplate(TestComponent, template)
64+
.createAsync(TestComponent)
65+
.then((fixture) {
66+
fixture.detectChanges();
67+
var refs = fixture.debugElement.children[0].getLocal("refs");
68+
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
69+
fixture.detectChanges();
70+
expect(fixture.nativeElement).toHaveText("foo");
71+
fixture.componentInstance.currentTplRef = null;
72+
fixture.detectChanges();
73+
expect(fixture.nativeElement).toHaveText("");
74+
async.done();
75+
});
76+
}));
77+
it(
78+
"should swap content if TemplateRef changes",
79+
inject([TestComponentBuilder, AsyncTestCompleter],
80+
(TestComponentBuilder tcb, async) {
81+
var template =
82+
'''<tpl-refs #refs="tplRefs"><template>foo</template><template>bar</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>''';
83+
tcb
84+
.overrideTemplate(TestComponent, template)
85+
.createAsync(TestComponent)
86+
.then((fixture) {
87+
fixture.detectChanges();
88+
var refs = fixture.debugElement.children[0].getLocal("refs");
89+
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
90+
fixture.detectChanges();
91+
expect(fixture.nativeElement).toHaveText("foo");
92+
fixture.componentInstance.currentTplRef = refs.tplRefs.last;
93+
fixture.detectChanges();
94+
expect(fixture.nativeElement).toHaveText("bar");
95+
async.done();
96+
});
97+
}));
98+
});
99+
}
100+
101+
@Directive(selector: "tpl-refs", exportAs: "tplRefs")
102+
class CaptureTplRefs {
103+
@ContentChildren(TemplateRef)
104+
QueryList<TemplateRef> tplRefs;
105+
}
106+
107+
@Component(
108+
selector: "test-cmp",
109+
directives: const [NgTemplateOutlet, CaptureTplRefs],
110+
template: "")
111+
class TestComponent {
112+
TemplateRef currentTplRef;
113+
}

test/public_api_spec.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ var NG_COMMON = [
7676
"NgFormControl",
7777
"NgFormModel",
7878
"NgIf",
79+
"NgTemplateOutlet",
7980
"NgModel",
8081
"NgSelectOption",
8182
"NgStyle",

0 commit comments

Comments
 (0)