diff --git a/public/docs/_examples/structural-directives/ts/.gitignore b/public/docs/_examples/structural-directives/ts/.gitignore new file mode 100644 index 0000000000..2cb7d2a2e9 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/.gitignore @@ -0,0 +1 @@ +**/*.js diff --git a/public/docs/_examples/structural-directives/ts/app/boot.ts b/public/docs/_examples/structural-directives/ts/app/boot.ts new file mode 100644 index 0000000000..da28d75daf --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/app/boot.ts @@ -0,0 +1,4 @@ +import {bootstrap} from 'angular2/platform/browser'; +import {StructuralDirectivesComponent} from './structural-directives.component'; + +bootstrap(StructuralDirectivesComponent); diff --git a/public/docs/_examples/structural-directives/ts/app/heavy-loader.component.ts b/public/docs/_examples/structural-directives/ts/app/heavy-loader.component.ts new file mode 100644 index 0000000000..3ec6f43b57 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/app/heavy-loader.component.ts @@ -0,0 +1,35 @@ +// #docregion +import {Component, Input, Output} from 'angular2/core'; + +let nextId = 1; + +@Component({ + selector: 'heavy-loader', + template: 'heavy loader #{{id}} on duty!' +}) +export class HeavyLoaderComponent { + id = nextId++; + @Input() logs: string[]; + + ngOnInit() { + // Mock todo: get 10,000 rows of data from the server + this._log(`heavy-loader ${this.id} initialized, + loading 10,000 rows of data from the server`); + } + + ngOnDestroy() { + // Mock todo: clean-up + this._log(`heavy-loader ${this.id} destroyed, cleaning up`); + } + + private _log(msg: string) { + this.logs.push(msg); + this._tick(); + } + + // Triggers the next round of Angular change detection + // after one turn of the JavaScript cycle + // ensuring display of msg added in onDestroy + private _tick() { setTimeout(() => { }, 0); } +} +// #enddocregion diff --git a/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html b/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html new file mode 100644 index 0000000000..c7aa615932 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html @@ -0,0 +1,109 @@ + + +

Structural Directives

+ + + +
{{hero}}
+
{{hero}}
+ + +
+ + + +
+ + + +
+ + + + +

+ condition is true and ngIf is true. +

+

+ condition is false and ngIf is false. +

+ + +

+ condition is false and myUnless is true. +

+ +

+ condition is true and myUnless is false. +

+ + +
+ + +
+ + +
+ +
+ + +
+ +

heavy-loader log:

+
{{message}}
+ + +
+ + +

+ Hip! +

+ +

+ Hooray! +

+ + +
+ + + + +

+ Our heroes are true! +

+ + + + + +
+ + + + + +
{{ hero }}
+ + + + + diff --git a/public/docs/_examples/structural-directives/ts/app/structural-directives.component.ts b/public/docs/_examples/structural-directives/ts/app/structural-directives.component.ts new file mode 100644 index 0000000000..4174edb05f --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/app/structural-directives.component.ts @@ -0,0 +1,21 @@ +// #docplaster +// #docregion +import {Component, Input, Output} from 'angular2/core'; +import {UnlessDirective} from './unless.directive'; +import {HeavyLoaderComponent} from './heavy-loader.component'; + +@Component({ + selector: 'structural-directives', + templateUrl: 'app/structural-directives.component.html', + styles: ['button { min-width: 100px; }'], + directives: [UnlessDirective, HeavyLoaderComponent] +}) +export class StructuralDirectivesComponent { + heroes = ['Mr. Nice', 'Narco', 'Bombasto']; + hero = this.heroes[0]; + condition = true; + isVisible = true; + logs: string[] = []; + status = 'ready'; +} +//#enddocregion diff --git a/public/docs/_examples/structural-directives/ts/app/unless.directive.ts b/public/docs/_examples/structural-directives/ts/app/unless.directive.ts new file mode 100644 index 0000000000..76f84b6408 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/app/unless.directive.ts @@ -0,0 +1,33 @@ +// #docplaster +// #docregion +// #docregion unless-declaration +import {Directive, Input} from 'angular2/core'; + +// #enddocregion unless-declaration +import {TemplateRef, ViewContainerRef} from 'angular2/core'; + +// #docregion unless-declaration +@Directive({ selector: '[myUnless]' }) +export class UnlessDirective { + // #enddocregion unless-declaration + + // #docregion unless-constructor + constructor( + private _templateRef: TemplateRef, + private _viewContainer: ViewContainerRef + ) { } + // #enddocregion unless-constructor + + // #docregion unless-set + @Input() set myUnless(condition: boolean) { + if (!condition) { + this._viewContainer.createEmbeddedView(this._templateRef); + } else { + this._viewContainer.clear(); + } + } + // #enddocregion unless-set + // #docregion unless-declaration +} +// #enddocregion unless-declaration +// #enddocregion diff --git a/public/docs/_examples/structural-directives/ts/example-config.json b/public/docs/_examples/structural-directives/ts/example-config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/structural-directives/ts/index.html b/public/docs/_examples/structural-directives/ts/index.html new file mode 100644 index 0000000000..15ef8d06e9 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/index.html @@ -0,0 +1,25 @@ + + + + + + Angular 2 Structural Directives + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/structural-directives/ts/package.json b/public/docs/_examples/structural-directives/ts/package.json new file mode 100644 index 0000000000..342877e5bf --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/package.json @@ -0,0 +1,42 @@ +{ + "name": "angular2-examples-master", + "version": "1.0.0", + "description": "Master package.json, the superset of all dependencies for all of the _example package.json files.", + "main": "index.js", + "scripts": { + "tsc": "tsc", + "tsc:w": "tsc -w", + "lite": "lite-server", + "live": "live-server", + "start": "npm run lite", + "go": "concurrent \"npm run tsc:w\" \"npm run start\" ", + "test": "karma start karma.conf.js", + "build-and-test": "npm run tsc && npm run test" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "angular2": "2.0.0-alpha.53", + "systemjs": "0.19.6", + "es6-promise": "^3.0.2", + "es6-shim": "^0.33.3", + "reflect-metadata": "0.1.2", + "rxjs": "5.0.0-alpha.14", + "zone.js": "0.5.8", + "bootstrap": "^3.3.6" + }, + "devDependencies": { + "concurrently": "^1.0.0", + "lite-server": "^1.3.1", + "live-server": "^0.8.2", + "typescript": "^1.7.3", + "jasmine-core":"~2.1.0", + "karma": "^0.12.23", + "karma-chrome-launcher": "^0.1.4", + "karma-cli": "^0.0.4", + "karma-jasmine": "^0.3.6", + "rimraf": "^2.4.3" + } + +} diff --git a/public/docs/_examples/structural-directives/ts/plnkr.json b/public/docs/_examples/structural-directives/ts/plnkr.json new file mode 100644 index 0000000000..32bfd6302a --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/plnkr.json @@ -0,0 +1,8 @@ +{ + "description": "Structural directives", + "files": ["!**/*.d.ts", "!**/*.js"], + "tags": [ + "structural", "directives", "template", "ngIf", + "ngSwitch", "ngFor" + ] +} diff --git a/public/docs/ts/latest/guide/_data.json b/public/docs/ts/latest/guide/_data.json index aa2fb4dcc4..02453a3398 100644 --- a/public/docs/ts/latest/guide/_data.json +++ b/public/docs/ts/latest/guide/_data.json @@ -22,7 +22,7 @@ "title": "User Input", "intro": "User input triggers DOM events. We listen to those events with EventBindings that funnel updated values back into our components and models." }, - + "forms": { "title": "Forms", "intro": "A form creates a cohesive, effective, and compelling data entry experience. An Angular form coordinates a set of data-bound user controls, tracks changes, validates input, and presents errors." @@ -32,29 +32,34 @@ "title": "Dependency Injection", "intro": "Angular's dependency injection system creates and delivers dependent services \"just-in-time\"." }, - + "template-syntax": { "title": "Template Syntax", "intro": "How to write templates that display data and consume user events with the help of data binding." }, - + "pipes": { "title": "Pipes", "intro": "Pipes transform displayed values within a template" }, - + "attribute-directives": { "title": "Attribute Directives", "intro": "Attribute directives attach behavior to elements." }, + "structural-directives": { + "title": "Structural Directives", + "intro": "Angular has a powerful template engine that lets us easily manipulate the DOM structure of our elements." + }, + "hierarchical-dependency-injection": { "title": "Hierarchical Injectors", "intro": "Angular's hierarchical dependency injection system supports nested injectors in parallel with the component tree." }, - + "glossary": { "title": "Glossary", "intro": "Brief definitions of the most important words in the Angular 2 vocabulary" } -} \ No newline at end of file +} diff --git a/public/docs/ts/latest/guide/attribute-directives.jade b/public/docs/ts/latest/guide/attribute-directives.jade index b9ce0fa14b..f27ec8b9c3 100644 --- a/public/docs/ts/latest/guide/attribute-directives.jade +++ b/public/docs/ts/latest/guide/attribute-directives.jade @@ -22,7 +22,7 @@ include ../../../../_includes/_util-fns The *Component* is really a directive with a template. It's the most common of the three directives and we write lots of them as we build our application. - The *Structural* directive changes the DOM layout by adding and removing DOM elements. + The [*Structural* directive](structural-directives.html) changes the DOM layout by adding and removing DOM elements. [NgFor](template-syntax.html#ng-for) and [NgIf](template-syntax.html#ng-if) are two familiar examples. The *Attribute* directive changes the appearance or behavior of an element. diff --git a/public/docs/ts/latest/guide/structural-directives.jade b/public/docs/ts/latest/guide/structural-directives.jade new file mode 100644 index 0000000000..7cf6392ed0 --- /dev/null +++ b/public/docs/ts/latest/guide/structural-directives.jade @@ -0,0 +1,335 @@ +include ../../../../_includes/_util-fns + +:marked + One of the defining features of a single page application is its manipulation + of the DOM tree. Instead of serving a whole new page every time a user + navigates, whole sections of the DOM appear and disappear according + to the application state. In this chapter we'll to look at how Angular + manipulates the DOM and how we can do it ourselves in our own directives. + + In this chapter we will + - [learn what structural directives are](#definition) + - [study *ngIf*](#ng-if) + - [discover the <template> element](#template) + - [understand the asterisk (\*) in **ngFor*](#asterisk) + - [write our own structural directive](#unless) + + [Live example](/resources/live-examples/structural-directives/ts/plnkr.html) + + +.l-main-section +:marked + ## What are structural directives? + + There are three kinds of Angular directives: + 1. Components + 1. Attribute directives + 1. Structural directives + + The *Component* is really a directive with a template. + It's the most common of the three directives and we write lots of them as we build our application. + + The [*Attribute* directive](attribute-directives.html) changes the appearance or behavior of an element. + The built-in [NgStyle](template-syntax.html#ng-style) directive, for example, + can change several element styles at the same time. + We can use it to render text bold, italic, and lime green by binding to a + component property that requests such a sickening result. + + A *Structural* directive changes the DOM layout by adding and removing DOM elements. + We've seen three of the built-in structural directives in other chapters: [ngIf](template-syntax.html#ngIf), + [ngSwitch](template-syntax.html#ngSwitch) and [ngFor](template-syntax.html#ngFor). + ++makeExample('structural-directives/ts/app/structural-directives.component.html', 'structural-directives')(format=".") + + + +.l-main-section +:marked + ## NgIf Case Study + + Let’s focus on `ngIf`. It's a great example of a structural + directive: it takes a boolean and makes an entire chunk of DOM appear + or disappear. + ++makeExample('structural-directives/ts/app/structural-directives.component.html', 'ngIf')(format=".") + +:marked + The `ngIf` directive does not hide the element. + Using browser developer tools we can see that, when the condition is true, the top + paragraph is in the DOM and the bottom disused paragraph is completely + absent from the DOM! In its place are empty `