feat(cb-ts-to-js): add es6 examples
update docshredder to shred .es6 optimized focus gulp task convert imports and metadate sections add DI section add host and query metadata section add intro fix capitalization and grammar
This commit is contained in:
parent
64a8754386
commit
12eb19fa3c
11
gulpfile.js
11
gulpfile.js
|
@ -247,15 +247,16 @@ function findAndRunE2eTests(filter, outputFile) {
|
|||
e2eSpecPaths.forEach(function(specPath) {
|
||||
// get all of the examples under each dir where a pcFilename is found
|
||||
localExamplePaths = getExamplePaths(specPath, true);
|
||||
// Filter by language
|
||||
localExamplePaths = localExamplePaths.filter(function (fn) {
|
||||
return fn.match('/'+lang+'$') != null;
|
||||
});
|
||||
// Filter by example name
|
||||
if (filter) {
|
||||
localExamplePaths = localExamplePaths.filter(function (fn) {
|
||||
return fn.match(filter) != null;
|
||||
})
|
||||
}
|
||||
// Filter by language, also supports variations like js-es6
|
||||
localExamplePaths = localExamplePaths.filter(function (fn) {
|
||||
return fn.match('/'+lang+'(?:-[^/]*)?$') != null;
|
||||
});
|
||||
localExamplePaths.forEach(function(examplePath) {
|
||||
examplePaths.push(examplePath);
|
||||
})
|
||||
|
@ -1270,7 +1271,7 @@ function apiExamplesWatch(postShredAction) {
|
|||
}
|
||||
|
||||
function devGuideExamplesWatch(shredOptions, postShredAction, focus) {
|
||||
var watchPattern = focus ? '**/{' + focus + ',cb-' + focus+ '}/**/*.*' : '**/*.*';
|
||||
var watchPattern = focus ? '{' + focus + ',cb-' + focus+ '}/**/*.*' : '**/*.*';
|
||||
var includePattern = path.join(shredOptions.examplesDir, watchPattern);
|
||||
// removed this version because gulp.watch has the same glob issue that dgeni has.
|
||||
// var excludePattern = '!' + path.join(shredOptions.examplesDir, '**/node_modules/**/*.*');
|
||||
|
|
|
@ -11,6 +11,7 @@ wallaby.js
|
|||
|
||||
_test-output
|
||||
**/ts/**/*.js
|
||||
**/js-es6*/**/*.js
|
||||
**/ts-snippets/**/*.js
|
||||
*.d.ts
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail",
|
||||
"build:cli": "ng build",
|
||||
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
|
||||
"build:babel": "babel app -d app --extensions \".es6\" --source-maps",
|
||||
"copy-dist-files": "node ./copy-dist-files.js",
|
||||
"i18n": "ng-xi18n"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"presets": [
|
||||
"es2015",
|
||||
"angular2"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class DataService {
|
||||
constructor() {
|
||||
}
|
||||
getHeroName() {
|
||||
return 'Windstorm';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import {
|
||||
Attribute,
|
||||
Component,
|
||||
Inject,
|
||||
Optional,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-title',
|
||||
template: `
|
||||
<h1>{{titlePrefix}} {{title}}</h1>
|
||||
<button (click)="ok()">OK</button>
|
||||
<p>{{ msg }}</p>
|
||||
`
|
||||
})
|
||||
class TitleComponent {
|
||||
msg = '';
|
||||
constructor(
|
||||
@Inject('titlePrefix') @Optional() titlePrefix,
|
||||
@Attribute('title') title
|
||||
) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@Component({
|
||||
selector: 'hero-di-inject-additional',
|
||||
template: `<hero-title title="Tour of Heroes">
|
||||
</hero-title>`
|
||||
})
|
||||
class AppComponent { }
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TitleComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class HeroesDIInjectAdditionalModule { }
|
|
@ -0,0 +1,22 @@
|
|||
import { Component, Inject, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-di-inject',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
class HeroComponent {
|
||||
constructor(@Inject('heroName') name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
providers: [ { provide: 'heroName', useValue: 'Windstorm' } ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesDIInjectModule { }
|
|
@ -0,0 +1,26 @@
|
|||
import { Component, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-di',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
|
||||
class HeroComponent {
|
||||
name;
|
||||
constructor(dataService: DataService) {
|
||||
this.name = dataService.getHeroName();
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
providers: [ DataService ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesDIModule { }
|
|
@ -0,0 +1,73 @@
|
|||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'my-confirm',
|
||||
template: `
|
||||
<button (click)="onOkClick()">
|
||||
{{okMsg}}
|
||||
</button>
|
||||
<button (click)="onNotOkClick()">
|
||||
{{notOkMsg}}
|
||||
</button>
|
||||
`
|
||||
})
|
||||
class ConfirmComponent {
|
||||
@Input() okMsg;
|
||||
@Input('cancelMsg') notOkMsg;
|
||||
@Output() ok =
|
||||
new EventEmitter();
|
||||
@Output('cancel') notOk =
|
||||
new EventEmitter();
|
||||
|
||||
onOkClick() {
|
||||
this.ok.next(true);
|
||||
}
|
||||
onNotOkClick() {
|
||||
this.notOk.next(true);
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'hero-io',
|
||||
template: `
|
||||
<my-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</my-confirm>
|
||||
<span *ngIf="okClicked">OK clicked</span>
|
||||
<span *ngIf="cancelClicked">Cancel clicked</span>
|
||||
`
|
||||
})
|
||||
class AppComponent {
|
||||
okClicked;
|
||||
cancelClicked;
|
||||
|
||||
onOk() {
|
||||
this.okClicked = true;
|
||||
}
|
||||
onCancel() {
|
||||
this.cancelClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ConfirmComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class HeroesIOModule { }
|
|
@ -0,0 +1,27 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
// #enddocregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'hero-lifecycle',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
// #docregion
|
||||
class HeroComponent{
|
||||
name;
|
||||
ngOnInit() {
|
||||
this.name = 'Windstorm';
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesLifecycleModule { }
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// #docplaster
|
||||
// #docregion metadata
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hero-view',
|
||||
template:
|
||||
'<h1>Hero: {{getName()}}</h1>'
|
||||
})
|
||||
// #docregion appexport
|
||||
// #docregion class
|
||||
export class HeroComponent {
|
||||
title = 'Hero Detail';
|
||||
getName() {return 'Windstorm'; }
|
||||
}
|
||||
// #enddocregion class
|
||||
// #enddocregion appexport
|
||||
// #enddocregion metadata
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesModule { }
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
import {
|
||||
Component,
|
||||
HostBinding,
|
||||
HostListener,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'heroes-bindings',
|
||||
template: `
|
||||
<h1 [class.active]="active">
|
||||
Tour of Heroes
|
||||
</h1>
|
||||
`
|
||||
})
|
||||
class HeroesComponent {
|
||||
@HostBinding() title = 'Tooltip content';
|
||||
@HostBinding('class.heading') hClass = true;
|
||||
active;
|
||||
|
||||
constructor() {}
|
||||
|
||||
@HostListener('click')
|
||||
clicked() {
|
||||
this.active = !this.active;
|
||||
}
|
||||
|
||||
@HostListener('dblclick', ['$event'])
|
||||
doubleClicked(evt) {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroesComponent ],
|
||||
bootstrap: [ HeroesComponent ]
|
||||
})
|
||||
export class HeroesHostBindingsModule { }
|
|
@ -0,0 +1,88 @@
|
|||
import {
|
||||
Component,
|
||||
ViewChildren,
|
||||
ContentChild,
|
||||
QueryList,
|
||||
Input,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'active-label',
|
||||
template: `<span class="active-label"
|
||||
*ngIf="active">
|
||||
Active
|
||||
</span>`
|
||||
})
|
||||
class ActiveLabelComponent {
|
||||
active;
|
||||
|
||||
activate() {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
// #docregion content
|
||||
@Component({
|
||||
selector: 'a-hero',
|
||||
template: `<h2 [class.active]=active>
|
||||
{{hero.name}}
|
||||
<ng-content></ng-content>
|
||||
</h2>`
|
||||
})
|
||||
class HeroComponent {
|
||||
@Input() hero;
|
||||
active;
|
||||
|
||||
@ContentChild(ActiveLabelComponent)
|
||||
label;
|
||||
|
||||
activate() {
|
||||
this.active = true;
|
||||
this.label.activate();
|
||||
}
|
||||
}
|
||||
// #enddocregion content
|
||||
|
||||
|
||||
// #docregion view
|
||||
@Component({
|
||||
selector: 'heroes-queries',
|
||||
template: `
|
||||
<a-hero *ngFor="let hero of heroData"
|
||||
[hero]="hero">
|
||||
<active-label></active-label>
|
||||
</a-hero>
|
||||
<button (click)="activate()">
|
||||
Activate
|
||||
</button>
|
||||
`
|
||||
})
|
||||
class HeroesQueriesComponent {
|
||||
heroData = [
|
||||
{id: 1, name: 'Windstorm'},
|
||||
{id: 2, name: 'Superman'}
|
||||
];
|
||||
|
||||
@ViewChildren(HeroComponent)
|
||||
heroCmps;
|
||||
|
||||
activate() {
|
||||
this.heroCmps.forEach(
|
||||
(cmp) => cmp.activate()
|
||||
);
|
||||
}
|
||||
}
|
||||
// #enddocregion view
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
HeroesQueriesComponent,
|
||||
HeroComponent,
|
||||
ActiveLabelComponent
|
||||
],
|
||||
bootstrap: [ HeroesQueriesComponent ]
|
||||
})
|
||||
export class HeroesQueriesModule { }
|
|
@ -0,0 +1,30 @@
|
|||
/* tslint:disable no-unused-variable */
|
||||
// #docregion ng2import
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import {
|
||||
LocationStrategy,
|
||||
HashLocationStrategy
|
||||
} from '@angular/common';
|
||||
// #enddocregion ng2import
|
||||
|
||||
// #docregion appimport
|
||||
import { HeroComponent } from './hero.component';
|
||||
// #enddocregion appimport
|
||||
|
||||
import { HeroesModule } from './hero.component';
|
||||
import { HeroesLifecycleModule } from './hero-lifecycle.component';
|
||||
import { HeroesDIModule } from './hero-di.component';
|
||||
import { HeroesDIInjectModule } from './hero-di-inject.component';
|
||||
import { HeroesDIInjectAdditionalModule } from './hero-di-inject-additional.component';
|
||||
import { HeroesIOModule } from './hero-io.component';
|
||||
import { HeroesHostBindingsModule } from './heroes-bindings.component';
|
||||
import { HeroesQueriesModule } from './heroes-queries.component';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(HeroesModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesLifecycleModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesDIModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesDIInjectModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesDIInjectAdditionalModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesIOModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesHostBindingsModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesQueriesModule);
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"build": "build:babel",
|
||||
"run": "http-server:e2e"
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/reflect-metadata/Reflect.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('app').catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a id="toc"></a>
|
||||
<h1>TypeScript to JavaScript</h1>
|
||||
<a href="#class-metadata">Classes and Class Metadata</a><br>
|
||||
<a href="#property-metadata">Input and Output Metadata</a><br>
|
||||
<a href="#dependency-injection">Dependency Injection</a><br>
|
||||
<a href="#other-property-metadata">Host and Query Metadata</a><br>
|
||||
|
||||
<hr>
|
||||
<h4 id="class-metadata">Classes and Class Metadata</h4>
|
||||
<hero-view id="class-metadata">Loading hero-view...</hero-view>
|
||||
<hero-lifecycle>Loading hero-lifecycle...</hero-lifecycle>
|
||||
|
||||
<hr>
|
||||
<h4 id="property-metadata">Input and Output Metadata</h4>
|
||||
<hero-io>Loading hero-io...</hero-io>
|
||||
|
||||
<hr>
|
||||
<h4 id="dependency-injection">Dependency Injection</h4>
|
||||
<hero-di>Loading hero-di...</hero-di>
|
||||
<hero-di-inject>Loading hero-di-inject...</hero-di-inject>
|
||||
<hero-di-inject-additional>Loading hero-di-inject-additional...</hero-di-inject-additional>
|
||||
|
||||
<hr>
|
||||
<h4 id="other-property-metadata">Host and Query Metadata</h4>
|
||||
<heroes-bindings>Loading heroes-bindings...</heroes-bindings>
|
||||
<heroes-queries id="other-property-metadata">Loading heroes-queries...</heroes-queries>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"description": "TypeScript to JavaScript",
|
||||
"files":[
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js"
|
||||
],
|
||||
"tags":["cookbook"]
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"presets": [
|
||||
"es2015"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
export class DataService {
|
||||
constructor() {
|
||||
}
|
||||
getHeroName() {
|
||||
return 'Windstorm';
|
||||
}
|
||||
}
|
||||
|
||||
DataService.annotations = [
|
||||
new Injectable()
|
||||
];
|
|
@ -0,0 +1,61 @@
|
|||
import {
|
||||
Attribute,
|
||||
Component,
|
||||
Inject,
|
||||
Optional,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
class TitleComponent {
|
||||
constructor(titlePrefix, title) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
this.msg = '';
|
||||
}
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
}
|
||||
|
||||
TitleComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-title',
|
||||
template: `
|
||||
<h1>{{titlePrefix}} {{title}}</h1>
|
||||
<button (click)="ok()">OK</button>
|
||||
<p>{{ msg }}</p>
|
||||
`
|
||||
})
|
||||
];
|
||||
|
||||
TitleComponent.parameters = [
|
||||
[new Optional(), new Inject('titlePrefix')],
|
||||
[new Attribute('title')]
|
||||
];
|
||||
// #enddocregion
|
||||
|
||||
class AppComponent {
|
||||
}
|
||||
AppComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-di-inject-additional',
|
||||
template: `<hero-title title="Tour of Heroes">
|
||||
</hero-title>`
|
||||
})
|
||||
];
|
||||
|
||||
export class HeroesDIInjectAdditionalModule { }
|
||||
|
||||
HeroesDIInjectAdditionalModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TitleComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,32 @@
|
|||
import { Component, Inject, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
class HeroComponent {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-di-inject',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
];
|
||||
|
||||
HeroComponent.parameters = [
|
||||
[new Inject('heroName')]
|
||||
];
|
||||
// #enddocregion
|
||||
|
||||
export class HeroesDIInjectModule { }
|
||||
|
||||
HeroesDIInjectModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
providers: [ { provide: 'heroName', useValue: 'Windstorm' } ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,35 @@
|
|||
import { Component, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
|
||||
// #docregion
|
||||
class HeroComponent {
|
||||
constructor(dataService) {
|
||||
this.name = dataService.getHeroName();
|
||||
}
|
||||
}
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-di',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
];
|
||||
|
||||
HeroComponent.parameters = [
|
||||
[DataService]
|
||||
];
|
||||
|
||||
// #enddocregion
|
||||
|
||||
export class HeroesDIModule { }
|
||||
|
||||
HeroesDIModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
providers: [ DataService ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,85 @@
|
|||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
class ConfirmComponent {
|
||||
constructor(){
|
||||
this.ok = new EventEmitter();
|
||||
this.notOk = new EventEmitter();
|
||||
}
|
||||
onOkClick() {
|
||||
this.ok.next(true);
|
||||
}
|
||||
onNotOkClick() {
|
||||
this.notOk.next(true);
|
||||
}
|
||||
}
|
||||
|
||||
ConfirmComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'my-confirm',
|
||||
template: `
|
||||
<button (click)="onOkClick()">
|
||||
{{okMsg}}
|
||||
</button>
|
||||
<button (click)="onNotOkClick()">
|
||||
{{notOkMsg}}
|
||||
</button>
|
||||
`,
|
||||
inputs: [
|
||||
'okMsg',
|
||||
'notOkMsg: cancelMsg'
|
||||
],
|
||||
outputs: [
|
||||
'ok',
|
||||
'notOk: cancel'
|
||||
]
|
||||
})
|
||||
];
|
||||
// #enddocregion
|
||||
|
||||
class AppComponent {
|
||||
constructor(){
|
||||
}
|
||||
onOk() {
|
||||
this.okClicked = true;
|
||||
}
|
||||
onCancel() {
|
||||
this.cancelClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
AppComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-io',
|
||||
template: `
|
||||
<my-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</my-confirm>
|
||||
<span *ngIf="okClicked">OK clicked</span>
|
||||
<span *ngIf="cancelClicked">Cancel clicked</span>
|
||||
`
|
||||
})
|
||||
];
|
||||
|
||||
|
||||
export class HeroesIOModule { }
|
||||
|
||||
HeroesIOModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ConfirmComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,31 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
// #enddocregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
class HeroComponent {
|
||||
ngOnInit() {
|
||||
this.name = 'Windstorm';
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-lifecycle',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
];
|
||||
|
||||
export class HeroesLifecycleModule { }
|
||||
|
||||
HeroesLifecycleModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,37 @@
|
|||
// #docplaster
|
||||
// #docregion metadata
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion class
|
||||
// #docregion appexport
|
||||
export class HeroComponent {
|
||||
construct() {
|
||||
this.title = 'Hero Detail';
|
||||
}
|
||||
getName() {return 'Windstorm'; }
|
||||
}
|
||||
// #enddocregion appexport
|
||||
// #enddocregion class
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-view',
|
||||
template: '<h1>Hero: {{getName()}}</h1>'
|
||||
})
|
||||
];
|
||||
// #enddocregion metadata
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
export class HeroesModule { }
|
||||
|
||||
HeroesModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
];
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
import {
|
||||
Component,
|
||||
HostBinding,
|
||||
HostListener,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
class HeroesComponent {
|
||||
constructor() {
|
||||
this.title = 'Tooltip content';
|
||||
this.hClass = true;
|
||||
}
|
||||
|
||||
clicked() {
|
||||
this.active = !this.active;
|
||||
}
|
||||
|
||||
doubleClicked(evt) {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
HeroesComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'heroes-bindings',
|
||||
template: `<h1 [class.active]="active">
|
||||
Tour of Heroes
|
||||
</h1>`,
|
||||
host: {
|
||||
'[title]': 'title',
|
||||
'[class.heading]': 'hClass',
|
||||
'(click)': 'clicked()',
|
||||
'(dblclick)': 'doubleClicked($event)'
|
||||
}
|
||||
})
|
||||
];
|
||||
// #enddocregion
|
||||
|
||||
export class HeroesHostBindingsModule { }
|
||||
|
||||
HeroesHostBindingsModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroesComponent ],
|
||||
bootstrap: [ HeroesComponent ]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,98 @@
|
|||
import {
|
||||
Component,
|
||||
ViewChildren,
|
||||
ContentChild,
|
||||
QueryList,
|
||||
Input,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
class ActiveLabelComponent {
|
||||
activate() {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
ActiveLabelComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'active-label',
|
||||
template: `
|
||||
<span class="active-label" *ngIf="active">
|
||||
Active
|
||||
</span>`
|
||||
})
|
||||
];
|
||||
|
||||
// #docregion content
|
||||
class HeroComponent {
|
||||
activate() {
|
||||
this.active = true;
|
||||
this.label.activate();
|
||||
}
|
||||
}
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'a-hero',
|
||||
template: `<h2 [class.active]=active>
|
||||
{{hero.name}}
|
||||
<ng-content></ng-content>
|
||||
</h2>`,
|
||||
inputs: ['hero'],
|
||||
queries: {
|
||||
label: new ContentChild(ActiveLabelComponent)
|
||||
}
|
||||
})
|
||||
];
|
||||
// #enddocregion content
|
||||
|
||||
|
||||
// #docregion view
|
||||
class HeroesQueriesComponent {
|
||||
constructor(){
|
||||
this.heroData = [
|
||||
{id: 1, name: 'Windstorm'},
|
||||
{id: 2, name: 'Superman'}
|
||||
];
|
||||
}
|
||||
|
||||
activate() {
|
||||
this.heroCmps.forEach(
|
||||
(cmp) => cmp.activate()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
HeroesQueriesComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'heroes-queries',
|
||||
template: `
|
||||
<a-hero *ngFor="let hero of heroData"
|
||||
[hero]="hero">
|
||||
<active-label></active-label>
|
||||
</a-hero>
|
||||
<button (click)="activate()">
|
||||
Activate
|
||||
</button>
|
||||
`,
|
||||
queries: {
|
||||
heroCmps: new ViewChildren(HeroComponent)
|
||||
}
|
||||
})
|
||||
];
|
||||
// #enddocregion view
|
||||
|
||||
export class HeroesQueriesModule { }
|
||||
|
||||
HeroesQueriesModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
HeroesQueriesComponent,
|
||||
HeroComponent,
|
||||
ActiveLabelComponent
|
||||
],
|
||||
bootstrap: [ HeroesQueriesComponent ]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,30 @@
|
|||
/* tslint:disable no-unused-variable */
|
||||
// #docregion ng2import
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import {
|
||||
LocationStrategy,
|
||||
HashLocationStrategy
|
||||
} from '@angular/common';
|
||||
// #enddocregion ng2import
|
||||
|
||||
// #docregion appimport
|
||||
import { HeroComponent } from './hero.component';
|
||||
// #enddocregion appimport
|
||||
|
||||
import { HeroesModule } from './hero.component';
|
||||
import { HeroesLifecycleModule } from './hero-lifecycle.component';
|
||||
import { HeroesDIModule } from './hero-di.component';
|
||||
import { HeroesDIInjectModule } from './hero-di-inject.component';
|
||||
import { HeroesDIInjectAdditionalModule } from './hero-di-inject-additional.component';
|
||||
import { HeroesIOModule } from './hero-io.component';
|
||||
import { HeroesHostBindingsModule } from './heroes-bindings.component';
|
||||
import { HeroesQueriesModule } from './heroes-queries.component';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(HeroesModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesLifecycleModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesDIModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesDIInjectModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesDIInjectAdditionalModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesIOModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesHostBindingsModule);
|
||||
platformBrowserDynamic().bootstrapModule(HeroesQueriesModule);
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"build": "build:babel",
|
||||
"run": "http-server:e2e"
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/reflect-metadata/Reflect.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('app').catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a id="toc"></a>
|
||||
<h1>TypeScript to JavaScript</h1>
|
||||
<a href="#class-metadata">Classes and Class Metadata</a><br>
|
||||
<a href="#property-metadata">Input and Output Metadata</a><br>
|
||||
<a href="#dependency-injection">Dependency Injection</a><br>
|
||||
<a href="#other-property-metadata">Host and Query Metadata</a><br>
|
||||
<my-app></my-app>
|
||||
|
||||
<hr>
|
||||
<h4 id="class-metadata">Classes and Class Metadata</h4>
|
||||
<hero-view id="class-metadata">Loading hero-view...</hero-view>
|
||||
<hero-lifecycle>Loading hero-lifecycle...</hero-lifecycle>
|
||||
|
||||
<hr>
|
||||
<h4 id="property-metadata">Input and Output Metadata</h4>
|
||||
<hero-io>Loading hero-io...</hero-io>
|
||||
|
||||
<hr>
|
||||
<h4 id="dependency-injection">Dependency Injection</h4>
|
||||
<hero-di>Loading hero-di...</hero-di>
|
||||
<hero-di-inject>Loading hero-di-inject...</hero-di-inject>
|
||||
<hero-di-inject-additional>Loading hero-di-inject-additional...</hero-di-inject-additional>
|
||||
|
||||
<hr>
|
||||
<h4 id="other-property-metadata">Host and Query Metadata</h4>
|
||||
<heroes-bindings>Loading heroes-bindings...</heroes-bindings>
|
||||
<heroes-queries id="other-property-metadata">Loading heroes-queries...</heroes-queries>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"description": "TypeScript to JavaScript",
|
||||
"files":[
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js"
|
||||
],
|
||||
"tags":["cookbook"]
|
||||
}
|
|
@ -9,10 +9,7 @@
|
|||
'<p>{{ msg }}</p>'
|
||||
}).Class({
|
||||
constructor: [
|
||||
[
|
||||
new ng.core.Optional(),
|
||||
new ng.core.Inject('titlePrefix')
|
||||
],
|
||||
[ new ng.core.Optional(), new ng.core.Inject('titlePrefix') ],
|
||||
new ng.core.Attribute('title'),
|
||||
function(titlePrefix, title) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
|
@ -33,7 +30,7 @@
|
|||
}).Class({
|
||||
constructor: function() { }
|
||||
});
|
||||
|
||||
|
||||
app.HeroesDIInjectAdditionalModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
(function(app) {
|
||||
|
@ -35,11 +35,12 @@
|
|||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
.Class({
|
||||
constructor:
|
||||
[new ng.core.Inject('heroName'),
|
||||
function(name) {
|
||||
this.name = name;
|
||||
}]
|
||||
constructor: [
|
||||
new ng.core.Inject('heroName'),
|
||||
function(name) {
|
||||
this.name = name;
|
||||
}
|
||||
]
|
||||
});
|
||||
// #enddocregion ctor
|
||||
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
.Class({
|
||||
constructor:
|
||||
[app.DataService,
|
||||
function(service) {
|
||||
this.name = service.getHeroName();
|
||||
}]
|
||||
constructor: [
|
||||
app.DataService,
|
||||
function(service) {
|
||||
this.name = service.getHeroName();
|
||||
}
|
||||
]
|
||||
});
|
||||
// #enddocregion
|
||||
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
function HeroComponent(dataService) {
|
||||
this.name = dataService.getHeroName();
|
||||
}
|
||||
|
||||
HeroComponent.parameters = [
|
||||
app.DataService
|
||||
];
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-di',
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
// #docregion component
|
||||
var HeroComponent = ng.core.Component({
|
||||
selector: 'hero-view-2',
|
||||
template:
|
||||
'<h1>Name: {{getName()}}</h1>',
|
||||
template: '<h1>Name: {{getName()}}</h1>',
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {
|
||||
|
|
|
@ -10,10 +10,9 @@
|
|||
})
|
||||
];
|
||||
// #docregion
|
||||
HeroComponent.prototype.ngOnInit =
|
||||
function() {
|
||||
this.name = 'Windstorm';
|
||||
};
|
||||
HeroComponent.prototype.ngOnInit = function() {
|
||||
this.name = 'Windstorm';
|
||||
};
|
||||
// #enddocregion
|
||||
|
||||
app.HeroesLifecycleModule =
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
HeroComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-view',
|
||||
template:
|
||||
'<h1>Hero: {{getName()}}</h1>'
|
||||
template: '<h1>Hero: {{getName()}}</h1>'
|
||||
})
|
||||
];
|
||||
// #docregion constructorproto
|
||||
HeroComponent.prototype.getName =
|
||||
function() {return 'Windstorm';};
|
||||
|
||||
HeroComponent.prototype.getName = function() {return 'Windstorm';};
|
||||
// #enddocregion constructorproto
|
||||
// #enddocregion metadata
|
||||
|
||||
|
|
|
@ -4,12 +4,9 @@
|
|||
// #enddocregion appimport
|
||||
|
||||
// #docregion ng2import
|
||||
var platformBrowserDynamic =
|
||||
ng.platformBrowserDynamic.platformBrowserDynamic;
|
||||
var LocationStrategy =
|
||||
ng.common.LocationStrategy;
|
||||
var HashLocationStrategy =
|
||||
ng.common.HashLocationStrategy;
|
||||
var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic;
|
||||
var LocationStrategy = ng.common.LocationStrategy;
|
||||
var HashLocationStrategy = ng.common.HashLocationStrategy;
|
||||
// #enddocregion ng2import
|
||||
|
||||
// #docregion appimport
|
||||
|
|
|
@ -19,12 +19,9 @@ import { BrowserModule } from '@angular/platform-browser';
|
|||
class TitleComponent {
|
||||
private msg: string = '';
|
||||
constructor(
|
||||
@Inject('titlePrefix')
|
||||
@Optional()
|
||||
private titlePrefix: string,
|
||||
@Attribute('title')
|
||||
private title: string) {
|
||||
}
|
||||
@Inject('titlePrefix') @Optional() private titlePrefix: string,
|
||||
@Attribute('title') private title: string
|
||||
) { }
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
|
|
|
@ -7,10 +7,7 @@ import { BrowserModule } from '@angular/platform-browser';
|
|||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
class HeroComponent {
|
||||
constructor(
|
||||
@Inject('heroName')
|
||||
private name: string) {
|
||||
}
|
||||
constructor(@Inject('heroName') private name: string) { }
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import { DataService } from './data.service';
|
|||
selector: 'hero-di',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
|
||||
class HeroComponent {
|
||||
name: string;
|
||||
constructor(dataService: DataService) {
|
||||
|
|
|
@ -10,8 +10,7 @@ import { BrowserModule } from '@angular/platform-browser';
|
|||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
// #docregion
|
||||
class HeroComponent
|
||||
implements OnInit {
|
||||
class HeroComponent implements OnInit {
|
||||
name: string;
|
||||
ngOnInit() {
|
||||
this.name = 'Windstorm';
|
||||
|
|
|
@ -9,14 +9,15 @@ import { BrowserModule } from '@angular/platform-browser';
|
|||
// #docregion
|
||||
@Component({
|
||||
selector: 'heroes-bindings',
|
||||
template: `<h1 [class.active]="active">
|
||||
Tour of Heroes
|
||||
</h1>`
|
||||
template: `
|
||||
<h1 [class.active]="active">
|
||||
Tour of Heroes
|
||||
</h1>
|
||||
`
|
||||
})
|
||||
class HeroesComponent {
|
||||
@HostBinding() title = 'Tooltip content';
|
||||
@HostBinding('class.heading')
|
||||
hClass = true;
|
||||
@HostBinding('class.heading') hClass = true;
|
||||
active: boolean;
|
||||
|
||||
constructor() {}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
"@angular/router": "~3.1.1",
|
||||
"@angular/upgrade": "~2.1.1",
|
||||
|
||||
"angular-in-memory-web-api": "~0.1.13",
|
||||
"angular-in-memory-web-api": "~0.1.14",
|
||||
"core-js": "^2.4.1",
|
||||
"reflect-metadata": "^0.1.8",
|
||||
"rollup": "^0.36.0",
|
||||
|
@ -51,6 +51,9 @@
|
|||
"@types/selenium-webdriver": "^2.53.32",
|
||||
"angular2-template-loader": "^0.4.0",
|
||||
"awesome-typescript-loader": "^2.2.4",
|
||||
"babel-cli": "^6.16.0",
|
||||
"babel-preset-angular2": "^0.0.2",
|
||||
"babel-preset-es2015": "^6.16.0",
|
||||
"canonical-path": "0.0.2",
|
||||
"concurrently": "^3.0.0",
|
||||
"css-loader": "^0.25.0",
|
||||
|
|
|
@ -16,6 +16,8 @@ include ../../../../_includes/_util-fns
|
|||
:marked
|
||||
## Table of contents
|
||||
|
||||
[From TS to ES6 to ES5](#from-ts)
|
||||
|
||||
[Modularity: imports and exports](#modularity)
|
||||
|
||||
[Classes and Class Metadata](#class-metadata)
|
||||
|
@ -24,90 +26,127 @@ include ../../../../_includes/_util-fns
|
|||
|
||||
[Dependency Injection](#dependency-injection)
|
||||
|
||||
[Host and Query Metadata](#other-property-metadata)
|
||||
[Host and Query Metadata](#host-query-metadata)
|
||||
|
||||
**Run and compare the live <live-example name="cb-ts-to-js">TypeScript</live-example> and <live-example name="cb-ts-to-js" lang="js">JavaScript</live-example>
|
||||
code shown in this cookbook.**
|
||||
|
||||
a(id="from-ts")
|
||||
.l-main-section
|
||||
:marked
|
||||
## From TS to ES6 to ES5
|
||||
|
||||
Since TypeScript is a superset of ES6 JavaScript, and ES6 itself is a superset of ES5, the
|
||||
transformation of Typescript code all the way to ES5 javascript can be seen as "shedding"
|
||||
features.
|
||||
|
||||
When going from TypeScript to ES6 with decorators, we mostly remove
|
||||
[type annotations](https://www.typescriptlang.org/docs/handbook/basic-types.html)
|
||||
, such as `string` or `boolean`, and
|
||||
[class property modifiers](http://www.typescriptlang.org/docs/handbook/classes.html#public-private-and-protected-modifiers)
|
||||
such as `public` and `private`.
|
||||
The exception is type annotations used for dependency injection, which can be kept.
|
||||
|
||||
Going from ES6 with decorators to plain ES6 JavaScript we lose all
|
||||
[decorators](https://www.typescriptlang.org/docs/handbook/decorators.html)
|
||||
and the remaining type annotations.
|
||||
We also lose class properties, which now have to be declared in the class constructor.
|
||||
|
||||
Finally, in the transition from ES6 to ES5 JavaScript the main missing features are `import`
|
||||
statements and `class` declarations.
|
||||
|
||||
For ES6 transpilation we recommend using a similar setup as our TypeScript quickstart,
|
||||
replacing TypeScript with [Babel](https://babeljs.io/) using the `es2015` preset.
|
||||
To use decorators and annotations with Babel, install the
|
||||
[`angular2`](https://github.com/shuhei/babel-plugin-angular2-annotations) preset as well.
|
||||
|
||||
a(id="modularity")
|
||||
.l-main-section
|
||||
:marked
|
||||
## Importing and Exporting
|
||||
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th TypeScript
|
||||
th ES5 JavaScript
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Importing Angular Code
|
||||
### Importing Angular Code
|
||||
|
||||
In TypeScript code, Angular classes, functions, and other members
|
||||
are imported with TypeScript `import` statements:
|
||||
In TypeScript and ES6 JavaScript, Angular classes, functions, and other members are imported
|
||||
with ES6 `import` statements.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/main.ts', 'ng2import')(format="." )
|
||||
In ES5 JavaScript code, when using [the Angular packages](../glossary.html#!#scoped-package),
|
||||
we can access Angular code through the global `ng` object. In the nested members of this
|
||||
object we'll find everything we would import from `@angular` in TypeScript:
|
||||
|
||||
td
|
||||
:marked
|
||||
### Accessing Angular Code through the ng global
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/main.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/main.es6,
|
||||
cb-ts-to-js/js-es6/app/main.es6,
|
||||
cb-ts-to-js/js/app/main.js
|
||||
`,`
|
||||
ng2import,
|
||||
ng2import,
|
||||
ng2import,
|
||||
ng2import
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
In JavaScript code, when using
|
||||
[the Angular packages](../glossary.html#!#scoped-package),
|
||||
we can access Angular code through the global `ng` object. In the
|
||||
nested members of this object we'll find everything we would import
|
||||
from `@angular` in TypeScript:
|
||||
:marked
|
||||
### Importing and Exporting Application Code
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/main.js', 'ng2import')(format="." )
|
||||
Each file in an Angular TypeScript or ES6 JavaScript application constitutes a ES6 module.
|
||||
When we want to make something from a module available to other modules, we `export` it.
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Importing and Exporting Application Code
|
||||
In an Angular ES5 JavaScript application, we load each file to the page using a `<script>` tag.
|
||||
Each file can make things available to other files via the shared global `window` scope.
|
||||
|
||||
Each file in an Angular TypeScript application constitutes a
|
||||
TypeScript module. When we want to make something from a module available
|
||||
to other modules, we `export` it.
|
||||
We often introduce an application namespace object (such as `app`) onto `window` and attach
|
||||
everything we need to share to that namespace object.
|
||||
We also wrap our code in an
|
||||
[Immediately Invoked Function Expression (IIFE)](https://en.wikipedia.org/wiki/Immediately-invoked_function_expression).
|
||||
These practices together prevent our code from polluting the global scope.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/hero.component.ts', 'appexport')(format="." )
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero.component.es6,
|
||||
cb-ts-to-js/js/app/hero.component.js
|
||||
`,`
|
||||
appexport,
|
||||
appexport,
|
||||
appexport,
|
||||
appexport
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
:marked
|
||||
In other modules we can then `import` things that have been exported
|
||||
elsewhere.
|
||||
:marked
|
||||
Using Typescript or ES6 JavaScript, in other modules we can then `import` things that have been exported
|
||||
elsewhere.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/main.ts', 'appimport')(format="." )
|
||||
In ES5 JavaScript we can access anything using the shared namespace in other files.
|
||||
Note that the order of `<script>` tags on the page is significant.
|
||||
We must load a file that defines a shared member before a file that uses that member.
|
||||
|
||||
td
|
||||
:marked
|
||||
### Sharing Application Code
|
||||
|
||||
In an Angular JavaScript application, we load each file to the page
|
||||
using a `<script>` tag. Each file can make things available to other
|
||||
files via the shared global `window` scope.
|
||||
|
||||
We often introduce an application namespace
|
||||
object (such as `"app"`) onto `window` and attach everything we need
|
||||
to share to that namespace object.
|
||||
We also wrap our code in an
|
||||
[Immediately Invoked Function Expression (IIFE)](https://en.wikipedia.org/wiki/Immediately-invoked_function_expression).
|
||||
These practices together prevent our code from
|
||||
polluting the global scope.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero.component.js', 'appexport')(format="." )
|
||||
|
||||
:marked
|
||||
We can then access anything from this shared namespace in
|
||||
other files.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/main.js', 'appimport')(format="." )
|
||||
|
||||
:marked
|
||||
Note that the order of `<script>` tags on the page is significant.
|
||||
We must load a file that defines a shared member before
|
||||
a file that uses that member.
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/main.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/main.es6,
|
||||
cb-ts-to-js/js-es6/app/main.es6,
|
||||
cb-ts-to-js/js/app/main.js
|
||||
`,`
|
||||
appimport,
|
||||
appimport,
|
||||
appimport,
|
||||
appimport
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
|
@ -123,347 +162,329 @@ a(id="class-metadata")
|
|||
:marked
|
||||
## Classes and Class Metadata
|
||||
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th TypeScript
|
||||
th ES5 JavaScript
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Classes
|
||||
### Classes
|
||||
|
||||
We put most of our Angular TypeScript code into TypeScript classes.
|
||||
We put most of our Angular TypeScript or ES6 JavaScript code into classes. ES6 without decorators
|
||||
also does not have support for class properties, so they must be assigned inside the constructor.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/hero.component.ts', 'class')(format="." )
|
||||
ES5 JavaScript has no classes. We use the constructor pattern instead which works with
|
||||
Angular as well as classes do.
|
||||
|
||||
td
|
||||
:marked
|
||||
### Constructors and Prototypes
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero.component.es6,
|
||||
cb-ts-to-js/js/app/hero.component.js
|
||||
`,`
|
||||
class,
|
||||
class,
|
||||
class,
|
||||
constructorproto
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
ES5 JavaScript has no classes. We use the constructor
|
||||
pattern instead which works with Angular as well as classes do.
|
||||
:marked
|
||||
### Metadata
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero.component.js', 'constructorproto')(format="." )
|
||||
Using Typescript or ES6 with decorators, we have access to *decorators*.
|
||||
Most Angular classes have one or more *decorators* attached to provide configuration
|
||||
and metadata.
|
||||
For example, a component must have a
|
||||
[`@Component`](../api/core/index/Component-decorator.html) decorator.
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Metadata with Decorators
|
||||
In ES5/6 JavaScript we can instead attach an `annotations` array to a class/constructor
|
||||
to provide metadata.
|
||||
Each item in the array corresponds to a decorator.
|
||||
|
||||
Most Angular classes have one or more TypeScript *decorators*
|
||||
attached to provide configuration and metadata. For example,
|
||||
a component must have a [`@Component`](../api/core/index/Component-decorator.html) decorator.
|
||||
The pattern of creating a constructor and decorating it with metadata is so common that Angular
|
||||
provides an alternative ES5 convenience class API for it for ES5 JavaScript.
|
||||
This API lets us define everything in a single expression.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/hero.component.ts', 'metadata')(format="." )
|
||||
With this API we first call the `ng.core.Component` function, followed by a chained `Class`
|
||||
method call.
|
||||
The argument to `Class` is an object that defines the constructor and the instance methods
|
||||
of the component.
|
||||
Similar APIs are also available for other decorators. You can define a directive with
|
||||
`ng.core.Directive` or a pipe with `ng.core.Pipe`.
|
||||
|
||||
td
|
||||
:marked
|
||||
### Metadata with the Annotations Array
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero.component.es6,
|
||||
cb-ts-to-js/js/app/hero.component.js,
|
||||
cb-ts-to-js/js/app/hero-dsl.component.js
|
||||
`,`
|
||||
metadata,
|
||||
metadata,
|
||||
metadata,
|
||||
metadata,
|
||||
component
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with Class API
|
||||
`)
|
||||
|
||||
In JavaScript, we can attach an `annotations` array to a constructor
|
||||
to provide metadata.
|
||||
Each item in the array corresponds to a TypeScript decorator.
|
||||
:marked
|
||||
### Interfaces
|
||||
|
||||
In the following example, we create a new instance of `Component` that corresponds
|
||||
to the [`@Component`](../api/core/index/Component-decorator.html) TypeScript decorator.
|
||||
When defining classes that need to implement a certain method, it is common to use TypeScript
|
||||
interfaces that enforce that the method signature is correct.
|
||||
Component lifecycle methods like `ngOnInit` are one example of this pattern.
|
||||
`ngOnInit` is defined in the `OnInit` interface.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero.component.js', 'metadata')(format="." )
|
||||
TypeScript interfaces are purely for developer convenience and are not used by Angular at runtime.
|
||||
This means that in ES5/6 JavaScript code we don't need to substitute anything for interfaces.
|
||||
We can just implement the methods.
|
||||
|
||||
:marked
|
||||
### Metadata with The Class Convenience API
|
||||
|
||||
The pattern of creating a constructor and decorating it with metadata
|
||||
is so common that Angular provides an alternative convenience API for it.
|
||||
This API lets us define everything in a single expression.
|
||||
|
||||
With this API we first call the `ng.core.Component` function,
|
||||
followed by a chained `Class` method call. The argument to `Class`
|
||||
is an object that defines the constructor and the instance methods
|
||||
of the component:
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero-dsl.component.js', 'component')(format="." )
|
||||
|
||||
:marked
|
||||
Similar APIs are also available for other decorators. You can define a
|
||||
directive:
|
||||
|
||||
code-example.
|
||||
var MyDirective = ng.core.Directive({
|
||||
...
|
||||
}).Class({
|
||||
...
|
||||
});
|
||||
|
||||
:marked
|
||||
Or a pipe:
|
||||
|
||||
code-example.
|
||||
var MyPipe = ng.core.Pipe({
|
||||
name: 'myPipe'
|
||||
}).Class({
|
||||
...
|
||||
});
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Interfaces
|
||||
|
||||
When defining classes that need to implement a certain method, it
|
||||
is common to use TypeScript interfaces that enforce that the
|
||||
method signature is correct. Component lifecycle methods like `ngOnInit`
|
||||
are one example of this pattern. `ngOnInit` is defined in the `OnInit`
|
||||
interface.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/hero-lifecycle.component.ts')(format="." )
|
||||
|
||||
td
|
||||
:marked
|
||||
### Implementing Methods without Interfaces
|
||||
|
||||
TypeScript interfaces are purely for developer convenience
|
||||
and are not used by Angular at runtime. This means that in JavaScript
|
||||
code we don't need to substitute anything for interfaces. We can just
|
||||
implement the methods.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero-lifecycle.component.js')(format="." )
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero-lifecycle.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-lifecycle.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-lifecycle.component.es6,
|
||||
cb-ts-to-js/js/app/hero-lifecycle.component.js
|
||||
`,`
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
a(id="property-metadata")
|
||||
.l-main-section
|
||||
:marked
|
||||
## Input and Output Metadata
|
||||
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th TypeScript
|
||||
th ES5 JavaScript
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Input and Output Decorators
|
||||
### Input and Output Decorators
|
||||
|
||||
In TypeScript, property decorators are often used to provide additional metadata
|
||||
for components and directives.
|
||||
|
||||
For [inputs and outputs](../guide/template-syntax.html#inputs-outputs),
|
||||
we use `@Input` and `@Output` property decorators.
|
||||
They may optionally specify input and output binding names if we want them to be
|
||||
different from the class property names.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/hero-io.component.ts')(format="." )
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
In TypeScript we can also use the `inputs` and `outputs` array metadata
|
||||
instead of the `@Input` and `@Output` property decorators.
|
||||
td
|
||||
:marked
|
||||
### Inputs and Outputs in Component Metadata
|
||||
|
||||
There is no equivalent of a property decorator in ES5 JavaScript. Instead,
|
||||
we add comparable information to the `Component` (or `Directive`) metadata.
|
||||
|
||||
In this example, we add `inputs` and `outputs` array attributes
|
||||
containing the input and output property names.
|
||||
If we need a binding name that is different from the
|
||||
property itself, we use the `propertyName: bindingName` syntax.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero-io.component.js')(format="." )
|
||||
In TypeScript and ES6 with decorators, property decorators are often used to provide additional
|
||||
metadata for components and directives.
|
||||
For [inputs and outputs](../guide/template-syntax.html#inputs-outputs), we use `@Input` and
|
||||
`@Output` property decorators.
|
||||
They may optionally specify input and output binding names if we want them to be different
|
||||
from the class property names.
|
||||
|
||||
There is no equivalent of a property decorator in ES5/6 JavaScript.
|
||||
Instead, we add comparable information to the `Component` (or `Directive`) metadata.
|
||||
|
||||
In this example, we add `inputs` and `outputs` array attributes containing the input and
|
||||
output property names.
|
||||
If we need a binding name that is different from the property itself, we use the
|
||||
`propertyName: bindingName` syntax.
|
||||
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero-io.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-io.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-io.component.es6,
|
||||
cb-ts-to-js/js/app/hero-io.component.js
|
||||
`,`
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Dependency Injection
|
||||
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th TypeScript
|
||||
th ES5 JavaScript
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Injection by Type
|
||||
### Injection by Type
|
||||
|
||||
Angular can often use TypeScript type information to
|
||||
determine what needs to be injected.
|
||||
Angular can often use TypeScript type information to determine what needs to be injected.
|
||||
ES6 with decorators can also make use of type information.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/hero-di.component.ts')(format="." )
|
||||
Since no type information is available in ES5/6 JavaScript, we must identify "injectables" in
|
||||
some other way.
|
||||
|
||||
td
|
||||
:marked
|
||||
### Injection with Parameter Tokens
|
||||
We attach a `parameters` array to the constructor function.
|
||||
Each array item is the dependency injection token that identifies the thing to be injected.
|
||||
Often the token is the constructor function for the class-like dependency.
|
||||
|
||||
In ES6 the decorators need to be inside a nested array.
|
||||
When using the ES5 class convenience API, we can also supply the parameter tokens by wrapping
|
||||
the constructor in an array.
|
||||
|
||||
Since no type information is available in ES5 JavaScript,
|
||||
we must identify "injectables" in some other way.
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero-di.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-di.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-di.component.es6,
|
||||
cb-ts-to-js/js/app/hero-di.component.js,
|
||||
cb-ts-to-js/js/app/hero-di-inline.component.js
|
||||
`,`
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with Class API
|
||||
`)
|
||||
|
||||
We attach a `parameters` array to the constructor function.
|
||||
Each array item is the dependency injection token that identifies the thing to be injected.
|
||||
Often the token is the constructor function for the class-like dependency.
|
||||
:marked
|
||||
### Injection with the @Inject decorator
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero-di.component.js')(format="." )
|
||||
When the thing being injected doesn't correspond directly to a type, we use the
|
||||
`@Inject()` decorator to supply the injection token.
|
||||
In this example, we're injecting a string identified by the "heroName" token.
|
||||
|
||||
:marked
|
||||
When using the class convenience API, we can also supply the parameter
|
||||
tokens by wrapping the constructor in an array.
|
||||
In ES5/6 JavaScript we add the token string to the injection parameters array.
|
||||
Alternatively, when using the ES5 convenience class API we can create a token with the
|
||||
`Inject` method and add that to the constructor array in the annotations.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero-di-inline.component.js')(format="." )
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero-di-inject.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-di-inject.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-di-inject.component.es6,
|
||||
cb-ts-to-js/js/app/hero-di-inject.component.js,
|
||||
cb-ts-to-js/js/app/hero-di-inject.component.js
|
||||
`,`
|
||||
,
|
||||
,
|
||||
,
|
||||
parameters,
|
||||
ctor
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with Class API
|
||||
`)
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Injection with the @Inject decorator
|
||||
:marked
|
||||
### Additional Injection Decorators
|
||||
|
||||
When the thing being injected doesn't correspond directly to a type,
|
||||
we use the `@Inject()` decorator to supply the injection token.
|
||||
|
||||
In this example, we're injecting a string identified by the "heroName" token.
|
||||
We can attach additional decorators to constructor parameters to qualify the injection behavior.
|
||||
We can mark optional dependencies with the [`@Optional`](../api/core/index/Optional-decorator.html),
|
||||
inject host element attributes with [`@Attribute`](../api/core/index/Attribute-interface.html),
|
||||
inject content child queries with [`@ContentChild`](../api/core/index/ContentChild-decorator.html)
|
||||
and inject view child queries with [`@ViewChild`](../api/core/index/ViewChild-decorator.html)).
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/hero-di-inject.component.ts')(format="." )
|
||||
In ES6 JavaScript we just add the extra decorators to the nested injection parameters array.
|
||||
|
||||
td
|
||||
:marked
|
||||
### Injection with plain string tokens
|
||||
To achieve the same effect in ES5 JavaScript, use a nested array with the constructor
|
||||
array notation in which the injection information precedes the constructor function itself.
|
||||
|
||||
We can apply other additional parameter decorators such as
|
||||
[`@Host`](../api/core/index/Host-decorator.html) and
|
||||
[`@SkipSelf`](../api/core/index/SkipSelf-decorator.html) in the same way -
|
||||
by adding `new ng.core.Host()` or `ng.core.SkipSelf()` in the
|
||||
parameters array.
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-di-inject-additional.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-di-inject-additional.component.es6,
|
||||
cb-ts-to-js/js/app/hero-di-inject-additional.component.js
|
||||
`,`
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
In JavaScript we add the token string to the injection parameters array.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero-di-inject.component.js','parameters')(format="." )
|
||||
|
||||
:marked
|
||||
Alternatively, we can create a token with the `Inject` method and
|
||||
add that to the constructor array in the annotations like this:
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero-di-inject.component.js','ctor')(format="." )
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Additional Injection Decorators
|
||||
|
||||
We can attach additional decorators to constructor parameters
|
||||
to qualify the injection behavior. We can mark
|
||||
optional dependencies with the [`@Optional`](../api/core/index/Optional-decorator.html),
|
||||
inject host element attributes with [`@Attribute`](../api/core/index/Attribute-interface.html),
|
||||
inject content child queries with [`@ContentChild`](../api/core/index/ContentChild-decorator.html)
|
||||
and inject view child queries with [`@ViewChild`](../api/core/index/ViewChild-decorator.html)).
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts')(format="." )
|
||||
|
||||
td
|
||||
:marked
|
||||
### Additional Injection Metadata with Nested Arrays
|
||||
|
||||
To achieve the same effect in JavaScript, use the constructor array notation
|
||||
in which the injection information precedes the constructor function itself.
|
||||
|
||||
Use the injection support functions `Attribute`, `Host`, `Optional`, `Self`, `SkipSelf` to qualify dependency injection behavior.
|
||||
|
||||
Use a nested array to combine injection functions.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/hero-di-inject-additional.component.js')(format="." )
|
||||
|
||||
:marked
|
||||
We can apply other additional parameter decorators such as
|
||||
[`@Host`](../api/core/index/Host-decorator.html) and
|
||||
[`@SkipSelf`](../api/core/index/SkipSelf-decorator.html) in the same way -
|
||||
by adding `new ng.core.Host()` or `ng.core.SkipSelf()` in the
|
||||
parameters array.
|
||||
|
||||
|
||||
a(id="other-property-metadata")
|
||||
a(id="host-query-metadata")
|
||||
.l-main-section
|
||||
:marked
|
||||
## Host and Query Metadata
|
||||
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th TypeScript
|
||||
th ES5 JavaScript
|
||||
tr(style=top)
|
||||
### Host Decorators
|
||||
|
||||
In Typescript and ES6 with decorators we can use host property decorators to bind a host
|
||||
element to a component or directive.
|
||||
The [`@HostBinding`](../api/core/index/HostBinding-interface.html) decorator
|
||||
binds host element properties to component data properties.
|
||||
The [`@HostListener`](../api/core/index/HostListener-interface.html) decorator binds
|
||||
host element events to component event handlers.
|
||||
|
||||
When using ES5/6 we add a `host` attribute to the component metadata to achieve the
|
||||
same effect as `@HostBinding` and `@HostListener`.
|
||||
|
||||
td
|
||||
:marked
|
||||
### Host Decorators
|
||||
The `host` value is an object whose properties are host property and listener bindings:
|
||||
|
||||
* Each key follows regular Angular binding syntax: `[property]` for host bindings
|
||||
or `(event)` for host listeners.
|
||||
* Each value identifies the corresponding component property or method.
|
||||
|
||||
We can use host property decorators to bind a host element to a component or directive.
|
||||
The [`@HostBinding`](../api/core/index/HostBinding-interface.html) decorator
|
||||
binds host element properties to component data properties.
|
||||
The [`@HostListener`](../api/core/index/HostListener-interface.html) decorator bimds
|
||||
host element events to component event handlers.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/heroes-bindings.component.ts')(format="." )
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
In TypeScript we can also use `host` metadata
|
||||
instead of the `@HostBinding` and `@HostListener` property decorators.
|
||||
td
|
||||
:marked
|
||||
### Host Metadata
|
||||
|
||||
We add a `host` attribute to the component metadata to achieve the
|
||||
same effect as `@HostBinding` and `@HostListener`.
|
||||
|
||||
The `host` value is an object whose properties are host property and listener bindings:
|
||||
|
||||
* Each key follows regular Angular binding syntax: `[property]` for host bindings
|
||||
or `(event)` for host listeners.
|
||||
* Each value identifies the corresponding component property or method.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/heroes-bindings.component.js')(format="." )
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/heroes-bindings.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/heroes-bindings.component.es6,
|
||||
cb-ts-to-js/js-es6/app/heroes-bindings.component.es6,
|
||||
cb-ts-to-js/js/app/heroes-bindings.component.js
|
||||
`,`
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
In TypeScript and ES6 with decorators we can also use the `queries` metadata
|
||||
instead of the `@ViewChild` and `@ContentChild` property decorators.
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Query Decorators
|
||||
|
||||
There are several property decorators for querying the descendants of
|
||||
a component or directive.
|
||||
|
||||
The [`@ViewChild`](../api/core/index/ViewChild-decorator.html) and
|
||||
[`@ViewChildren`](../api/core/index/ViewChildren-decorator.html) property decorators
|
||||
allow a component to query instances of other components that are used in
|
||||
its view.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/heroes-queries.component.ts', 'view')(format="." )
|
||||
:marked
|
||||
### Query Decorators
|
||||
|
||||
There are several property decorators for querying the descendants of
|
||||
a component or directive.
|
||||
|
||||
The [`@ViewChild`](../api/core/index/ViewChild-decorator.html) and
|
||||
[`@ViewChildren`](../api/core/index/ViewChildren-decorator.html) property decorators
|
||||
allow a component to query instances of other components that are used in
|
||||
its view.
|
||||
|
||||
:marked
|
||||
The [`@ContentChild`](../api/core/index/ContentChild-decorator.html) and
|
||||
[`@ContentChildren`](../api/core/index/ContentChildren-decorator.html) property decorators
|
||||
allow a component to query instances of other components that have been projected
|
||||
into its view from elsewhere.
|
||||
|
||||
+makeExample('cb-ts-to-js/ts/app/heroes-queries.component.ts', 'content')(format="." )
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
In TypeScript we can also use the `queries` metadata
|
||||
instead of the `@ViewChild` and `@ContentChild` property decorators.
|
||||
td
|
||||
:marked
|
||||
### Query Metadata
|
||||
|
||||
We access a component's view children by adding a `queries` attribute to
|
||||
the component metadata. It should be an object where:
|
||||
|
||||
* Each key is the name of a component property that will hold the view children
|
||||
* Each value is an instance of either `ViewChild` or `ViewChildren`.
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/heroes-queries.component.js', 'view')(format="." )
|
||||
In ES5/6 JavaScript we access a component's view children by adding a `queries` attribute to
|
||||
the component metadata. It should be an object where:
|
||||
|
||||
* Each key is the name of a component property that will hold the view children
|
||||
* Each value is an instance of either `ViewChild` or `ViewChildren`.
|
||||
|
||||
:marked
|
||||
We add *content* child queries to the same `queries` attribute
|
||||
in the same manner, using instances of `ContentChild` or `ContentChildren`:
|
||||
|
||||
+makeExample('cb-ts-to-js/js/app/heroes-queries.component.js', 'content')(format="." )
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/heroes-queries.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/heroes-queries.component.es6,
|
||||
cb-ts-to-js/js-es6/app/heroes-queries.component.es6,
|
||||
cb-ts-to-js/js/app/heroes-queries.component.js
|
||||
`,`
|
||||
view,
|
||||
view,
|
||||
view,
|
||||
view
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
:marked
|
||||
The [`@ContentChild`](../api/core/index/ContentChild-decorator.html) and
|
||||
[`@ContentChildren`](../api/core/index/ContentChildren-decorator.html) property decorators
|
||||
allow a component to query instances of other components that have been projected
|
||||
into its view from elsewhere.
|
||||
|
||||
They can be added in the same way as [`@ViewChild`](../api/core/index/ViewChild-decorator.html) and
|
||||
[`@ViewChildren`](../api/core/index/ViewChildren-decorator.html).
|
||||
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/heroes-queries.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/heroes-queries.component.es6,
|
||||
cb-ts-to-js/js-es6/app/heroes-queries.component.es6,
|
||||
cb-ts-to-js/js/app/heroes-queries.component.js
|
||||
`,`
|
||||
content,
|
||||
content,
|
||||
content,
|
||||
content
|
||||
`,`
|
||||
Typescript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
|
|
@ -120,7 +120,7 @@ function createShredExamplePackage(shredOptions) {
|
|||
readFilesProcessor.basePath = "/";
|
||||
|
||||
// Specify collections of source files that should contain the documentation to extract
|
||||
var extns = ['*.ts', '*.html', '*.js', '*.css', '*.json', '*.dart', '*.yaml' ];
|
||||
var extns = ['*.ts', '*.html', '*.js', '*.css', '*.json', '*.dart', '*.yaml', '*.es6' ];
|
||||
var includeFiles = extns.map(function(extn) {
|
||||
if (options.includeSubdirs) {
|
||||
return path.join(options.examplesDir, '**', extn);
|
||||
|
|
|
@ -154,6 +154,7 @@ function getCommentInfo(extension) {
|
|||
switch (extension) {
|
||||
case 'ts':
|
||||
case 'js':
|
||||
case 'es6':
|
||||
case 'dart':
|
||||
commentInfo = {
|
||||
prefix: '//',
|
||||
|
|
Loading…
Reference in New Issue