docs(cb-ts-to-js): refactor sample code
This commit is contained in:
parent
b11438f211
commit
53f5538859
|
@ -1,4 +1,4 @@
|
|||
'use strict'; // necessary for es6 output in node
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
|
@ -9,7 +9,7 @@ describe('TypeScript to Javascript tests', function () {
|
|||
});
|
||||
|
||||
it('should display the basic component example', function () {
|
||||
testTag('hero-view', 'Hero: Windstorm');
|
||||
testTag('hero-view', 'Hero Detail: Windstorm');
|
||||
});
|
||||
|
||||
it('should display the component example with lifecycle methods', function () {
|
||||
|
@ -36,7 +36,7 @@ describe('TypeScript to Javascript tests', function () {
|
|||
|
||||
it('should support component with inputs and outputs', function () {
|
||||
let app = element(by.css('hero-io'));
|
||||
let confirmComponent = app.element(by.css('my-confirm'));
|
||||
let confirmComponent = app.element(by.css('app-confirm'));
|
||||
|
||||
confirmComponent.element(by.buttonText('OK')).click();
|
||||
expect(app.element(by.cssContainingText('span', 'OK clicked')).isPresent()).toBe(true);
|
||||
|
@ -46,11 +46,11 @@ describe('TypeScript to Javascript tests', function () {
|
|||
});
|
||||
|
||||
it('should support host bindings and host listeners', function() {
|
||||
let app = element(by.css('heroes-bindings'));
|
||||
let app = element(by.css('hero-host'));
|
||||
let h1 = app.element(by.css('h1'));
|
||||
|
||||
expect(app.getAttribute('class')).toBe('heading');
|
||||
expect(app.getAttribute('title')).toBe('Tooltip content');
|
||||
expect(app.getAttribute('title')).toContain('Tooltip');
|
||||
|
||||
h1.click();
|
||||
expect(h1.getAttribute('class')).toBe('active');
|
||||
|
@ -61,12 +61,12 @@ describe('TypeScript to Javascript tests', function () {
|
|||
});
|
||||
|
||||
it('should support content and view queries', function() {
|
||||
let app = element(by.css('heroes-queries'));
|
||||
let windstorm = app.element(by.css('a-hero:first-child'));
|
||||
let app = element(by.css('hero-queries'));
|
||||
let windstorm = app.element(by.css('view-child:first-child'));
|
||||
|
||||
app.element(by.buttonText('Activate')).click();
|
||||
app.element(by.css('button')).click();
|
||||
expect(windstorm.element(by.css('h2')).getAttribute('class')).toBe('active');
|
||||
expect(windstorm.element(by.css('active-label')).getText()).toBe('Active');
|
||||
expect(windstorm.element(by.css('content-child')).getText()).toBe('Active');
|
||||
});
|
||||
|
||||
function testTag(selector: string, expectedText: string) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'my-app',
|
||||
templateUrl: 'app.component.html',
|
||||
styles: [
|
||||
// See hero-di-inject-additional.component
|
||||
'hero-host, hero-host-meta { border: 1px dashed black; display: block; padding: 4px;}',
|
||||
'.heading {font-style: italic}'
|
||||
]
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'ES6 JavaScript with Decorators';
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<a id="toc"></a>
|
||||
<h1>{{title}}</h1>
|
||||
<a href="#class-metadata">Classes and Class Metadata</a><br>
|
||||
<a href="#io-metadata">Input and Output Decorators</a><br>
|
||||
<a href="#dependency-injection">Dependency Injection</a><br>
|
||||
<a href="#host-metadata">Host Metadata</a><br>
|
||||
<a href="#view-child-metadata">View and Child Metadata</a><br>
|
||||
|
||||
<hr>
|
||||
<h4 id="class-metadata">Classes and Class Metadata</h4>
|
||||
<hero-view></hero-view>
|
||||
<hero-lifecycle></hero-lifecycle>
|
||||
|
||||
<hr>
|
||||
<h4 id="io-metadata">Input and Output Metadata</h4>
|
||||
<hero-io></hero-io>
|
||||
|
||||
<hr>
|
||||
<h4 id="dependency-injection">Dependency Injection</h4>
|
||||
<hero-di></hero-di>
|
||||
<hero-di-inject></hero-di-inject>
|
||||
<hero-di-inject-additional></hero-di-inject-additional>
|
||||
|
||||
<hr>
|
||||
<h4 id="host-metadata">Host Metadata</h4>
|
||||
<hero-host></hero-host>
|
||||
<hero-host-meta></hero-host-meta>
|
||||
|
||||
<hr>
|
||||
<h4 id="view-child-metadata">View and Child Metadata</h4>
|
||||
<hero-queries></hero-queries>
|
|
@ -0,0 +1,55 @@
|
|||
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { ConfirmComponent } from './confirm.component';
|
||||
// #docregion appimport
|
||||
import { HeroComponent } from './hero.component';
|
||||
// #enddocregion appimport
|
||||
import { HeroComponent as HeroDIComponent } from './hero-di.component';
|
||||
import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component';
|
||||
import { HeroComponent as HeroDIInjectAdditionalComponent } from './hero-di-inject-additional.component';
|
||||
import { HeroHostComponent } from './hero-host.component';
|
||||
import { HeroHostMetaComponent } from './hero-host-meta.component';
|
||||
import { HeroIOComponent } from './hero-io.component';
|
||||
import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component';
|
||||
import { HeroQueriesComponent, ViewChildComponent, ContentChildComponent } from './hero-queries.component';
|
||||
import { HeroTitleComponent } from './hero-title.component';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ConfirmComponent,
|
||||
HeroComponent,
|
||||
HeroDIComponent,
|
||||
HeroDIInjectComponent,
|
||||
HeroDIInjectAdditionalComponent,
|
||||
HeroHostComponent, HeroHostMetaComponent,
|
||||
HeroIOComponent,
|
||||
HeroLifecycleComponent,
|
||||
HeroQueriesComponent, ViewChildComponent, ContentChildComponent,
|
||||
HeroTitleComponent
|
||||
],
|
||||
providers: [
|
||||
DataService,
|
||||
{ provide: 'heroName', useValue: 'Windstorm' }
|
||||
],
|
||||
bootstrap: [ AppComponent ],
|
||||
|
||||
// schemas: [ NO_ERRORS_SCHEMA ] // helpful for debugging
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
/* tslint:disable no-unused-variable */
|
||||
// #docregion ng2import
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import {
|
||||
LocationStrategy,
|
||||
HashLocationStrategy
|
||||
} from '@angular/common';
|
||||
// #enddocregion ng2import
|
|
@ -0,0 +1,22 @@
|
|||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'app-confirm',
|
||||
templateUrl: 'confirm.component.html'
|
||||
})
|
||||
export class ConfirmComponent {
|
||||
@Input() okMsg = '';
|
||||
@Input('cancelMsg') notOkMsg = '';
|
||||
@Output() ok = new EventEmitter();
|
||||
@Output('cancel') notOk = new EventEmitter();
|
||||
|
||||
onOkClick() {
|
||||
this.ok.emit(true);
|
||||
}
|
||||
onNotOkClick() {
|
||||
this.notOk.emit(true);
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
|
@ -2,8 +2,8 @@ import { Injectable } from '@angular/core';
|
|||
|
||||
@Injectable()
|
||||
export class DataService {
|
||||
constructor() {
|
||||
}
|
||||
constructor() { }
|
||||
|
||||
getHeroName() {
|
||||
return 'Windstorm';
|
||||
}
|
||||
|
|
|
@ -1,49 +1,7 @@
|
|||
import {
|
||||
Attribute,
|
||||
Component,
|
||||
Inject,
|
||||
Optional,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
// #docregion metadata
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'hero-title',
|
||||
templateUrl: 'title.component.html'
|
||||
})
|
||||
// #enddocregion metadata
|
||||
class TitleComponent {
|
||||
msg = '';
|
||||
constructor(
|
||||
@Inject('titlePrefix') @Optional() titlePrefix,
|
||||
@Attribute('title') title
|
||||
) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hero-di-inject-additional',
|
||||
template: `<hero-title title="Tour of Heroes">
|
||||
</hero-title>`
|
||||
template: `<hero-title title="Tour of Heroes"></hero-title>`
|
||||
})
|
||||
class AppComponent { }
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TitleComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class HeroesDIInjectAdditionalModule { }
|
||||
export class HeroComponent { }
|
||||
|
|
|
@ -1,22 +1,13 @@
|
|||
import { Component, Inject, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-di-inject',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
class HeroComponent {
|
||||
export 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 { }
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import { Component, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { DataService } from './data.service';
|
||||
|
||||
// #docregion
|
||||
|
@ -8,19 +6,10 @@ import { DataService } from './data.service';
|
|||
selector: 'hero-di',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
|
||||
class HeroComponent {
|
||||
name;
|
||||
export 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,44 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-host-meta',
|
||||
template: `
|
||||
<h1 [class.active]="active">Hero Host in Metadata</h1>
|
||||
<div>Heading clicks: {{clicks}}</div>
|
||||
`,
|
||||
host: {
|
||||
// HostBindings to the <hero-host-meta> element
|
||||
'[title]': 'title',
|
||||
'[class.heading]': 'headingClass',
|
||||
|
||||
// HostListeners on the entire <hero-host-meta> element
|
||||
'(click)': 'clicked()',
|
||||
'(mouseenter)': 'enter($event)',
|
||||
'(mouseleave)': 'leave($event)'
|
||||
},
|
||||
// Styles within (but excluding) the <hero-host-meta> element
|
||||
styles: ['.active {background-color: coral;}']
|
||||
})
|
||||
export class HeroHostMetaComponent {
|
||||
title = 'Hero Host in Metadata Tooltip';
|
||||
headingClass = true;
|
||||
|
||||
active = false;
|
||||
clicks = 0;
|
||||
|
||||
clicked() {
|
||||
this.clicks += 1;
|
||||
}
|
||||
|
||||
enter(event: Event) {
|
||||
this.active = true;
|
||||
this.headingClass = false;
|
||||
}
|
||||
|
||||
leave(event: Event) {
|
||||
this.active = false;
|
||||
this.headingClass = true;
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
|
@ -0,0 +1,39 @@
|
|||
import { Component, HostBinding, HostListener } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-host',
|
||||
template: `
|
||||
<h1 [class.active]="active">Hero Host in Decorators</h1>
|
||||
<div>Heading clicks: {{clicks}}</div>
|
||||
`,
|
||||
// Styles within (but excluding) the <hero-host> element
|
||||
styles: ['.active {background-color: yellow;}']
|
||||
})
|
||||
export class HeroHostComponent {
|
||||
// HostBindings to the <hero-host> element
|
||||
@HostBinding() title = 'Hero Host in Decorators Tooltip';
|
||||
@HostBinding('class.heading') headingClass = true;
|
||||
|
||||
active = false;
|
||||
clicks = 0;
|
||||
|
||||
// HostListeners on the entire <hero-host> element
|
||||
@HostListener('click')
|
||||
clicked() {
|
||||
this.clicks += 1;
|
||||
}
|
||||
|
||||
@HostListener('mouseenter', ['$event'])
|
||||
enter(event: Event) {
|
||||
this.active = true;
|
||||
this.headingClass = false;
|
||||
}
|
||||
|
||||
@HostListener('mouseleave', ['$event'])
|
||||
leave(event: Event) {
|
||||
this.active = false;
|
||||
this.headingClass = true;
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
|
@ -1,67 +1,26 @@
|
|||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'my-confirm',
|
||||
templateUrl: 'confirm.component.html'
|
||||
})
|
||||
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
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hero-io',
|
||||
template: `
|
||||
<my-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</my-confirm>
|
||||
<app-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</app-confirm>
|
||||
<span *ngIf="okClicked">OK clicked</span>
|
||||
<span *ngIf="cancelClicked">Cancel clicked</span>
|
||||
`
|
||||
})
|
||||
class AppComponent {
|
||||
okClicked;
|
||||
cancelClicked;
|
||||
export class HeroIOComponent {
|
||||
okClicked = false;
|
||||
cancelClicked = false;
|
||||
|
||||
onOk() {
|
||||
this.okClicked = true;
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
this.cancelClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ConfirmComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class HeroesIOModule { }
|
||||
|
|
|
@ -1,27 +1,14 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
// #enddocregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hero-lifecycle',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
// #docregion
|
||||
class HeroComponent{
|
||||
name;
|
||||
export class HeroComponent {
|
||||
name = '';
|
||||
ngOnInit() {
|
||||
this.name = 'Windstorm';
|
||||
// todo: fetch from server async
|
||||
setTimeout(() => this.name = 'Windstorm', 0);
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesLifecycleModule { }
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
import {
|
||||
Component,
|
||||
ContentChild,
|
||||
Input,
|
||||
QueryList,
|
||||
ViewChildren
|
||||
} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'content-child',
|
||||
template: `
|
||||
<span class="content-child" *ngIf="active">
|
||||
Active
|
||||
</span>`
|
||||
})
|
||||
export class ContentChildComponent {
|
||||
active = false;
|
||||
|
||||
activate() {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
// #docregion content
|
||||
@Component({
|
||||
selector: 'view-child',
|
||||
template: `
|
||||
<h2 [class.active]=active>
|
||||
{{hero.name}}
|
||||
<ng-content></ng-content>
|
||||
</h2>`,
|
||||
styles: ['.active {font-weight: bold; background-color: skyblue;}']
|
||||
})
|
||||
export class ViewChildComponent {
|
||||
@Input() hero;
|
||||
active = false;
|
||||
|
||||
@ContentChild(ContentChildComponent) content;
|
||||
|
||||
activate() {
|
||||
this.active = !this.active;
|
||||
this.content.activate();
|
||||
}
|
||||
}
|
||||
// #enddocregion content
|
||||
|
||||
////////////////////
|
||||
|
||||
// #docregion view
|
||||
@Component({
|
||||
selector: 'hero-queries',
|
||||
template: `
|
||||
<view-child *ngFor="let hero of heroData" [hero]="hero">
|
||||
<content-child></content-child>
|
||||
</view-child>
|
||||
<button (click)="activate()">{{buttonLabel}} All</button>
|
||||
`
|
||||
})
|
||||
export class HeroQueriesComponent {
|
||||
active = false;
|
||||
heroData = [
|
||||
{id: 1, name: 'Windstorm'},
|
||||
{id: 2, name: 'LaughingGas'}
|
||||
];
|
||||
|
||||
@ViewChildren(ViewChildComponent) views;
|
||||
|
||||
activate() {
|
||||
this.active = !this.active;
|
||||
this.views.forEach(
|
||||
view => view.activate()
|
||||
);
|
||||
}
|
||||
|
||||
get buttonLabel() {
|
||||
return this.active ? 'Deactivate' : 'Activate';
|
||||
}
|
||||
}
|
||||
// #enddocregion view
|
|
@ -0,0 +1,26 @@
|
|||
import { Attribute, Component, Inject, Optional } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
// #docregion templateUrl
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'hero-title',
|
||||
templateUrl: 'hero-title.component.html'
|
||||
})
|
||||
// #enddocregion templateUrl
|
||||
export class HeroTitleComponent {
|
||||
msg = '';
|
||||
constructor(
|
||||
@Inject('titlePrefix') @Optional() titlePrefix,
|
||||
@Attribute('title') title
|
||||
) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
// #docplaster
|
||||
// #docregion metadata
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
|
@ -6,24 +5,10 @@ import { Component } from '@angular/core';
|
|||
selector: 'hero-view',
|
||||
template: '<h1>{{title}}: {{getName()}}</h1>'
|
||||
})
|
||||
// #docregion appexport
|
||||
// #docregion class
|
||||
// #docregion appexport, class
|
||||
export class HeroComponent {
|
||||
title = 'Hero Detail';
|
||||
getName() {return 'Windstorm'; }
|
||||
}
|
||||
// #enddocregion class
|
||||
// #enddocregion appexport
|
||||
// #enddocregion appexport, class
|
||||
// #enddocregion metadata
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesModule { }
|
||||
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
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 { }
|
|
@ -1,88 +0,0 @@
|
|||
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 { }
|
|
@ -1,30 +1,4 @@
|
|||
/* tslint:disable no-unused-variable */
|
||||
// #docregion ng2import
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import {
|
||||
LocationStrategy,
|
||||
HashLocationStrategy
|
||||
} from '@angular/common';
|
||||
// #enddocregion ng2import
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
// #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);
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<title>TypeScript to JavaScript</title>
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
@ -20,32 +21,7 @@
|
|||
</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>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
export class AppComponent {
|
||||
constructor() {
|
||||
this.title = 'Plain ES6 JavaScript';
|
||||
}
|
||||
}
|
||||
|
||||
AppComponent.annotations = [
|
||||
new Component({
|
||||
moduleId: module.id,
|
||||
selector: 'my-app',
|
||||
templateUrl: 'app.component.html',
|
||||
styles: [
|
||||
// See hero-di-inject-additional.component
|
||||
'hero-host { border: 1px dashed black; display: block; padding: 4px;}',
|
||||
'.heading {font-style: italic}'
|
||||
]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,30 @@
|
|||
<a id="toc"></a>
|
||||
<h1>{{title}}</h1>
|
||||
<a href="#class-metadata">Classes and Class Metadata</a><br>
|
||||
<a href="#io-metadata">Input and Output Metadata</a><br>
|
||||
<a href="#dependency-injection">Dependency Injection</a><br>
|
||||
<a href="#host-metadata">Host Metadata</a><br>
|
||||
<a href="#view-child-metadata">View and Child Metadata</a><br>
|
||||
|
||||
<hr>
|
||||
<h4 id="class-metadata">Classes and Class Metadata</h4>
|
||||
<hero-view></hero-view>
|
||||
<hero-lifecycle></hero-lifecycle>
|
||||
|
||||
<hr>
|
||||
<h4 id="io-metadata">Input and Output Metadata</h4>
|
||||
<hero-io></hero-io>
|
||||
|
||||
<hr>
|
||||
<h4 id="dependency-injection">Dependency Injection</h4>
|
||||
<hero-di></hero-di>
|
||||
<hero-di-inject></hero-di-inject>
|
||||
<hero-di-inject-additional></hero-di-inject-additional>
|
||||
|
||||
<hr>
|
||||
<h4 id="host-metadata">Host Metadata</h4>
|
||||
<hero-host></hero-host>
|
||||
|
||||
<hr>
|
||||
<h4 id="view-child-metadata">View and Child Metadata</h4>
|
||||
<hero-queries></hero-queries>
|
|
@ -0,0 +1,56 @@
|
|||
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { ConfirmComponent } from './confirm.component';
|
||||
// #docregion appimport
|
||||
import { HeroComponent } from './hero.component';
|
||||
|
||||
// #enddocregion appimport
|
||||
import { HeroComponent as HeroDIComponent } from './hero-di.component';
|
||||
import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component';
|
||||
import { HeroComponent as HeroDIInjectAdditionalComponent } from './hero-di-inject-additional.component';
|
||||
import { HeroHostComponent } from './hero-host.component';
|
||||
import { HeroIOComponent } from './hero-io.component';
|
||||
import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component';
|
||||
import { HeroQueriesComponent, ViewChildComponent, ContentChildComponent } from './hero-queries.component';
|
||||
import { HeroTitleComponent } from './hero-title.component';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
|
||||
export class AppModule { }
|
||||
|
||||
AppModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ConfirmComponent,
|
||||
HeroComponent,
|
||||
HeroDIComponent,
|
||||
HeroDIInjectComponent,
|
||||
HeroDIInjectAdditionalComponent,
|
||||
HeroHostComponent,
|
||||
HeroIOComponent,
|
||||
HeroLifecycleComponent,
|
||||
HeroQueriesComponent, ViewChildComponent, ContentChildComponent,
|
||||
HeroTitleComponent
|
||||
],
|
||||
providers: [
|
||||
DataService,
|
||||
{ provide: 'heroName', useValue: 'Windstorm' }
|
||||
],
|
||||
bootstrap: [ AppComponent ],
|
||||
|
||||
// schemas: [ NO_ERRORS_SCHEMA ] // helpful for debugging
|
||||
})
|
||||
]
|
||||
|
||||
/* tslint:disable no-unused-variable */
|
||||
// #docregion ng2import
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import {
|
||||
LocationStrategy,
|
||||
HashLocationStrategy
|
||||
} from '@angular/common';
|
||||
// #enddocregion ng2import
|
|
@ -0,0 +1,32 @@
|
|||
import { Component, EventEmitter } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
export class ConfirmComponent {
|
||||
constructor(){
|
||||
this.ok = new EventEmitter();
|
||||
this.notOk = new EventEmitter();
|
||||
}
|
||||
onOkClick() {
|
||||
this.ok.emit(true);
|
||||
}
|
||||
onNotOkClick() {
|
||||
this.notOk.emit(true);
|
||||
}
|
||||
}
|
||||
|
||||
ConfirmComponent.annotations = [
|
||||
new Component({
|
||||
moduleId: module.id,
|
||||
selector: 'app-confirm',
|
||||
templateUrl: 'confirm.component.html',
|
||||
inputs: [
|
||||
'okMsg',
|
||||
'notOkMsg: cancelMsg'
|
||||
],
|
||||
outputs: [
|
||||
'ok',
|
||||
'notOk: cancel'
|
||||
]
|
||||
})
|
||||
];
|
||||
// #enddocregion
|
|
@ -1,60 +1,10 @@
|
|||
import {
|
||||
Attribute,
|
||||
Component,
|
||||
Inject,
|
||||
Optional,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
class TitleComponent {
|
||||
constructor(titlePrefix, title) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
this.msg = '';
|
||||
}
|
||||
export class HeroComponent { }
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
}
|
||||
|
||||
// #docregion metadata
|
||||
TitleComponent.annotations = [
|
||||
new Component({
|
||||
moduleId: module.id,
|
||||
selector: 'hero-title',
|
||||
templateUrl: 'title.component.html'
|
||||
})
|
||||
];
|
||||
// #enddocregion metadata
|
||||
|
||||
TitleComponent.parameters = [
|
||||
[new Optional(), new Inject('titlePrefix')],
|
||||
[new Attribute('title')]
|
||||
];
|
||||
// #enddocregion
|
||||
|
||||
class AppComponent {
|
||||
}
|
||||
AppComponent.annotations = [
|
||||
HeroComponent.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 ]
|
||||
template: `<hero-title title="Tour of Heroes"></hero-title>`
|
||||
})
|
||||
];
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Component, Inject, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
class HeroComponent {
|
||||
export class HeroComponent {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
@ -19,14 +18,3 @@ HeroComponent.parameters = [
|
|||
[new Inject('heroName')]
|
||||
];
|
||||
// #enddocregion
|
||||
|
||||
export class HeroesDIInjectModule { }
|
||||
|
||||
HeroesDIInjectModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
providers: [ { provide: 'heroName', useValue: 'Windstorm' } ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
];
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import { Component, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { DataService } from './data.service';
|
||||
|
||||
// #docregion
|
||||
class HeroComponent {
|
||||
export class HeroComponent {
|
||||
constructor(dataService) {
|
||||
this.name = dataService.getHeroName();
|
||||
}
|
||||
|
@ -22,14 +20,3 @@ HeroComponent.parameters = [
|
|||
];
|
||||
|
||||
// #enddocregion
|
||||
|
||||
export class HeroesDIModule { }
|
||||
|
||||
HeroesDIModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
providers: [ DataService ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
];
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
export class HeroHostComponent {
|
||||
constructor() {
|
||||
this.active = false;
|
||||
this.clicks = 0;
|
||||
this.headingClass = true;
|
||||
this.title = 'Hero Host Tooltip';
|
||||
}
|
||||
|
||||
clicked() {
|
||||
this.clicks += 1;
|
||||
}
|
||||
|
||||
enter(event) {
|
||||
this.active = true;
|
||||
this.headingClass = false;
|
||||
}
|
||||
|
||||
leave(event) {
|
||||
this.active = false;
|
||||
this.headingClass = true;
|
||||
}
|
||||
}
|
||||
|
||||
// #docregion metadata
|
||||
HeroHostComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-host',
|
||||
template: `
|
||||
<h1 [class.active]="active">Hero Host</h1>
|
||||
<div>Heading clicks: {{clicks}}</div>
|
||||
`,
|
||||
host: {
|
||||
// HostBindings to the <hero-host> element
|
||||
'[title]': 'title',
|
||||
'[class.heading]': 'headingClass',
|
||||
'(click)': 'clicked()',
|
||||
|
||||
// HostListeners on the entire <hero-host> element
|
||||
'(mouseenter)': 'enter($event)',
|
||||
'(mouseleave)': 'leave($event)'
|
||||
},
|
||||
// Styles within (but excluding) the <hero-host> element
|
||||
styles: ['.active {background-color: yellow;}']
|
||||
})
|
||||
];
|
||||
// #docregion metadata
|
||||
// #enddocregion
|
|
@ -1,79 +1,31 @@
|
|||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
class ConfirmComponent {
|
||||
constructor(){
|
||||
this.ok = new EventEmitter();
|
||||
this.notOk = new EventEmitter();
|
||||
export class HeroIOComponent {
|
||||
constructor() {
|
||||
this.okClicked = false;
|
||||
this.cancelClicked = false;
|
||||
}
|
||||
onOkClick() {
|
||||
this.ok.next(true);
|
||||
}
|
||||
onNotOkClick() {
|
||||
this.notOk.next(true);
|
||||
}
|
||||
}
|
||||
|
||||
ConfirmComponent.annotations = [
|
||||
new Component({
|
||||
moduleId: module.id,
|
||||
selector: 'my-confirm',
|
||||
templateUrl: 'confirm.component.html',
|
||||
inputs: [
|
||||
'okMsg',
|
||||
'notOkMsg: cancelMsg'
|
||||
],
|
||||
outputs: [
|
||||
'ok',
|
||||
'notOk: cancel'
|
||||
]
|
||||
})
|
||||
];
|
||||
// #enddocregion
|
||||
|
||||
class AppComponent {
|
||||
constructor(){
|
||||
}
|
||||
onOk() {
|
||||
this.okClicked = true;
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
this.cancelClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
AppComponent.annotations = [
|
||||
HeroIOComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-io',
|
||||
template: `
|
||||
<my-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</my-confirm>
|
||||
<app-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</app-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 ]
|
||||
})
|
||||
];
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
// #enddocregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
class HeroComponent {
|
||||
export class HeroComponent {
|
||||
ngOnInit() {
|
||||
this.name = 'Windstorm';
|
||||
// todo: fetch from server async
|
||||
setTimeout(() => this.name = 'Windstorm', 0);
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new Component({
|
||||
|
@ -19,13 +13,3 @@ HeroComponent.annotations = [
|
|||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
];
|
||||
|
||||
export class HeroesLifecycleModule { }
|
||||
|
||||
HeroesLifecycleModule.annotations = [
|
||||
new NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
];
|
|
@ -0,0 +1,97 @@
|
|||
import {
|
||||
Component,
|
||||
ContentChild,
|
||||
Input,
|
||||
QueryList,
|
||||
ViewChildren
|
||||
} from '@angular/core';
|
||||
|
||||
export class ContentChildComponent {
|
||||
constructor() {
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
activate() {
|
||||
this.active = !this.active;
|
||||
}
|
||||
}
|
||||
|
||||
ContentChildComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'content-child',
|
||||
template: `
|
||||
<span class="content-child" *ngIf="active">
|
||||
Active
|
||||
</span>`
|
||||
})
|
||||
];
|
||||
|
||||
////////////////////
|
||||
|
||||
// #docregion content
|
||||
export class ViewChildComponent {
|
||||
constructor() {
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
activate() {
|
||||
this.active = !this.active;
|
||||
this.content.activate();
|
||||
}
|
||||
}
|
||||
|
||||
ViewChildComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'view-child',
|
||||
template: `<h2 [class.active]=active>
|
||||
{{hero.name}}
|
||||
<ng-content></ng-content>
|
||||
</h2>`,
|
||||
styles: ['.active {font-weight: bold; background-color: skyblue;}'],
|
||||
inputs: ['hero'],
|
||||
queries: {
|
||||
content: new ContentChild(ContentChildComponent)
|
||||
}
|
||||
})
|
||||
];
|
||||
// #enddocregion content
|
||||
|
||||
////////////////////
|
||||
|
||||
// #docregion view
|
||||
export class HeroQueriesComponent {
|
||||
constructor(){
|
||||
this.active = false;
|
||||
this.heroData = [
|
||||
{id: 1, name: 'Windstorm'},
|
||||
{id: 2, name: 'LaughingGas'}
|
||||
];
|
||||
}
|
||||
|
||||
activate() {
|
||||
this.active = !this.active;
|
||||
this.views.forEach(
|
||||
view => view.activate()
|
||||
);
|
||||
}
|
||||
|
||||
get buttonLabel() {
|
||||
return this.active ? 'Deactivate' : 'Activate';
|
||||
}
|
||||
}
|
||||
|
||||
HeroQueriesComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'hero-queries',
|
||||
template: `
|
||||
<view-child *ngFor="let hero of heroData" [hero]="hero">
|
||||
<content-child></content-child>
|
||||
</view-child>
|
||||
<button (click)="activate()">{{buttonLabel}} All</button>
|
||||
`,
|
||||
queries: {
|
||||
views: new ViewChildren(ViewChildComponent)
|
||||
}
|
||||
})
|
||||
];
|
||||
// #enddocregion view
|
|
@ -0,0 +1,29 @@
|
|||
import { Attribute, Component, Inject, Optional } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
export class HeroTitleComponent {
|
||||
constructor(titlePrefix, title) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
this.msg = '';
|
||||
}
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
}
|
||||
|
||||
// #docregion templateUrl
|
||||
HeroTitleComponent.annotations = [
|
||||
new Component({
|
||||
moduleId: module.id,
|
||||
selector: 'hero-title',
|
||||
templateUrl: 'hero-title.component.html'
|
||||
})
|
||||
];
|
||||
// #enddocregion templateUrl
|
||||
|
||||
HeroTitleComponent.parameters = [
|
||||
[new Optional(), new Inject('titlePrefix')],
|
||||
[new Attribute('title')]
|
||||
];
|
|
@ -1,3 +1,4 @@
|
|||
<!-- #docregion -->
|
||||
<h1>{{titlePrefix}} {{title}}</h1>
|
||||
<button (click)="ok()">OK</button>
|
||||
<p>{{ msg }}</p>
|
|
@ -2,16 +2,14 @@
|
|||
// #docregion metadata
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion class
|
||||
// #docregion appexport
|
||||
// #docregion appexport, class
|
||||
export class HeroComponent {
|
||||
constructor() {
|
||||
this.title = 'Hero Detail';
|
||||
}
|
||||
getName() {return 'Windstorm'; }
|
||||
}
|
||||
// #enddocregion appexport
|
||||
// #enddocregion class
|
||||
// #enddocregion appexport, class
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new Component({
|
||||
|
@ -20,18 +18,3 @@ HeroComponent.annotations = [
|
|||
})
|
||||
];
|
||||
// #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 ]
|
||||
})
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
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 ]
|
||||
})
|
||||
];
|
|
@ -1,98 +0,0 @@
|
|||
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 ]
|
||||
})
|
||||
];
|
|
@ -1,30 +1,4 @@
|
|||
/* tslint:disable no-unused-variable */
|
||||
// #docregion ng2import
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import {
|
||||
LocationStrategy,
|
||||
HashLocationStrategy
|
||||
} from '@angular/common';
|
||||
// #enddocregion ng2import
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
// #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);
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<title>TypeScript to JavaScript</title>
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
@ -20,33 +21,7 @@
|
|||
</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>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<a id="toc"></a>
|
||||
<h1>{{title}}</h1>
|
||||
<a href="#class-metadata">Classes and Class Metadata</a><br>
|
||||
<a href="#interfaces">Interfaces</a><br>
|
||||
<a href="#io-metadata">Input and Output Metadata</a><br>
|
||||
<a href="#dependency-injection">Dependency Injection</a><br>
|
||||
<a href="#host-metadata">Host Metadata</a><br>
|
||||
<a href="#view-child-metadata">View and Child Metadata</a><br>
|
||||
|
||||
<hr>
|
||||
<h4 id="class-metadata">Classes and Class Metadata</h4>
|
||||
<hero-view></hero-view>
|
||||
<h4 id="class-metadata-dsl">Classes and Class Metadata (DSL)</h4>
|
||||
<hero-view-dsl></hero-view-dsl>
|
||||
|
||||
<hr>
|
||||
<h4 id="interfaces">Interfaces</h4>
|
||||
<hero-lifecycle></hero-lifecycle>
|
||||
<h4 id="interfaces-dsl">Interfaces (DSL)</h4>
|
||||
<hero-lifecycle-dsl></hero-lifecycle-dsl>
|
||||
|
||||
<hr>
|
||||
<h4 id="io-metadata">Input and Output Metadata</h4>
|
||||
<hero-io></hero-io>
|
||||
<h4 id="io-metadata-dsl">Input and Output Metadata (DSL)</h4>
|
||||
<hero-io-dsl></hero-io-dsl>
|
||||
|
||||
<hr>
|
||||
<h4 id="dependency-injection">Dependency Injection</h4>
|
||||
<hero-di></hero-di>
|
||||
<hero-di-inject></hero-di-inject>
|
||||
<hero-di-inject-additional></hero-di-inject-additional>
|
||||
|
||||
<h4 id="dependency-injection-dsl">Dependency Injection (DSL)</h4>
|
||||
<hero-di-dsl></hero-di-dsl>
|
||||
<hero-di-inject-dsl></hero-di-inject-dsl>
|
||||
<hero-di-inject-additional-dsl></hero-di-inject-additional-dsl>
|
||||
|
||||
<hr>
|
||||
<h4 id="host-metadata">Host Metadata</h4>
|
||||
<hero-host></hero-host>
|
||||
<h4 id="host-metadata-dsl">Host Metadata (DSL)</h4>
|
||||
<hero-host-dsl></hero-host-dsl>
|
||||
|
||||
<hr>
|
||||
<h4 id="view-child-metadata">View and Child Metadata (DSL)</h4>
|
||||
<hero-queries></hero-queries>
|
|
@ -0,0 +1,20 @@
|
|||
(function(app) {
|
||||
|
||||
app.AppComponent = AppComponent;
|
||||
function AppComponent() {
|
||||
this.title = 'ES5 JavaScript';
|
||||
}
|
||||
|
||||
AppComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'my-app',
|
||||
templateUrl: 'app/app.component.html',
|
||||
styles: [
|
||||
// See hero-di-inject-additional.component
|
||||
'hero-host, hero-host-dsl { border: 1px dashed black; display: block; padding: 4px;}',
|
||||
'.heading {font-style: italic}'
|
||||
]
|
||||
})
|
||||
];
|
||||
|
||||
})(window.app = window.app || {});
|
|
@ -0,0 +1,46 @@
|
|||
(function(app) {
|
||||
|
||||
app.AppModule = AppModule;
|
||||
function AppModule() { }
|
||||
|
||||
AppModule.annotations = [
|
||||
new ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
declarations: [
|
||||
app.AppComponent,
|
||||
app.ConfirmComponent, app.ConfirmDslComponent,
|
||||
app.HeroComponent, app.HeroDslComponent,
|
||||
app.HeroDIComponent, app.HeroDIDslComponent,
|
||||
app.HeroDIInjectComponent, app.HeroDIInjectDslComponent,
|
||||
app.HeroDIInjectAdditionalComponent, app.HeroDIInjectAdditionalDslComponent,
|
||||
app.HeroHostComponent, app.HeroHostDslComponent,
|
||||
app.HeroIOComponent, app.HeroIODslComponent,
|
||||
app.HeroLifecycleComponent, app.HeroLifecycleDslComponent,
|
||||
app.heroQueries.HeroQueriesComponent, app.heroQueries.ViewChildComponent, app.heroQueries.ContentChildComponent,
|
||||
app.HeroTitleComponent, app.HeroTitleDslComponent
|
||||
],
|
||||
providers: [
|
||||
app.DataService,
|
||||
{ provide: 'heroName', useValue: 'Windstorm' }
|
||||
],
|
||||
bootstrap: [ app.AppComponent ],
|
||||
|
||||
// schemas: [ ng.core.NO_ERRORS_SCHEMA ] // helpful for debugging!
|
||||
})
|
||||
]
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
|
||||
///// For documentation only /////
|
||||
(function () {
|
||||
// #docregion appimport
|
||||
var HeroComponent = app.HeroComponent;
|
||||
// #enddocregion appimport
|
||||
|
||||
// #docregion ng2import
|
||||
var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic;
|
||||
var LocationStrategy = ng.common.LocationStrategy;
|
||||
var HashLocationStrategy = ng.common.HashLocationStrategy;
|
||||
// #enddocregion ng2import
|
||||
})
|
|
@ -0,0 +1,73 @@
|
|||
(function(app) {
|
||||
|
||||
// #docregion
|
||||
app.ConfirmComponent = ConfirmComponent;
|
||||
|
||||
ConfirmComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'app-confirm',
|
||||
templateUrl: 'app/confirm.component.html',
|
||||
inputs: [
|
||||
'okMsg',
|
||||
'notOkMsg: cancelMsg'
|
||||
],
|
||||
outputs: [
|
||||
'ok',
|
||||
'notOk: cancel'
|
||||
]
|
||||
})
|
||||
];
|
||||
|
||||
function ConfirmComponent() {
|
||||
this.ok = new ng.core.EventEmitter();
|
||||
this.notOk = new ng.core.EventEmitter();
|
||||
}
|
||||
|
||||
ConfirmComponent.prototype.onOkClick = function() {
|
||||
this.ok.emit(true);
|
||||
}
|
||||
|
||||
ConfirmComponent.prototype.onNotOkClick = function() {
|
||||
this.notOk.emit(true);
|
||||
}
|
||||
|
||||
|
||||
// #enddocregion
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
/////// DSL version ////////
|
||||
|
||||
(function(app) {
|
||||
|
||||
// #docregion dsl
|
||||
app.ConfirmDslComponent = ng.core.Component({
|
||||
selector: 'app-confirm-dsl',
|
||||
templateUrl: 'app/confirm.component.html',
|
||||
inputs: [
|
||||
'okMsg',
|
||||
'notOkMsg: cancelMsg'
|
||||
],
|
||||
outputs: [
|
||||
'ok',
|
||||
'notOk: cancel'
|
||||
]
|
||||
})
|
||||
.Class({
|
||||
constructor: function ConfirmDslComponent() {
|
||||
this.ok = new ng.core.EventEmitter();
|
||||
this.notOk = new ng.core.EventEmitter();
|
||||
},
|
||||
|
||||
onOkClick: function() {
|
||||
this.ok.emit(true);
|
||||
},
|
||||
|
||||
onNotOkClick: function() {
|
||||
this.notOk.emit(true);
|
||||
}
|
||||
});
|
||||
|
||||
// #enddocregion dsl
|
||||
|
||||
})(window.app = window.app || {});
|
|
@ -1,13 +1,10 @@
|
|||
(function(app) {
|
||||
|
||||
function DataService() {
|
||||
}
|
||||
DataService.annotations = [
|
||||
new ng.core.Injectable()
|
||||
];
|
||||
app.DataService = DataService;
|
||||
function DataService() { }
|
||||
|
||||
DataService.prototype.getHeroName = function() {
|
||||
return 'Windstorm';
|
||||
};
|
||||
app.DataService = DataService;
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
|
|
@ -1,47 +1,26 @@
|
|||
(function(app) {
|
||||
|
||||
// #docregion
|
||||
// #docregion metadata
|
||||
var TitleComponent = ng.core.Component({
|
||||
selector: 'hero-title',
|
||||
templateUrl: 'app/title.component.html'
|
||||
})
|
||||
// #enddocregion metadata
|
||||
.Class({
|
||||
constructor: [
|
||||
[ new ng.core.Optional(), new ng.core.Inject('titlePrefix') ],
|
||||
new ng.core.Attribute('title'),
|
||||
function(titlePrefix, title) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
this.msg = '';
|
||||
}
|
||||
],
|
||||
ok: function() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
});
|
||||
// #enddocregion
|
||||
app.HeroDIInjectAdditionalComponent = HeroDIInjectAdditionalComponent;
|
||||
|
||||
var AppComponent = ng.core.Component({
|
||||
HeroDIInjectAdditionalComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-di-inject-additional',
|
||||
template: '<hero-title title="Tour of Heroes">' +
|
||||
'</hero-title>'
|
||||
}).Class({
|
||||
constructor: function() { }
|
||||
});
|
||||
template: '<hero-title title="Tour of Heroes"></hero-title>'
|
||||
})
|
||||
];
|
||||
|
||||
app.HeroesDIInjectAdditionalModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TitleComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
function HeroDIInjectAdditionalComponent() {}
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
////// DSL Version /////////
|
||||
(function(app) {
|
||||
|
||||
app.HeroDIInjectAdditionalDslComponent = ng.core.Component({
|
||||
selector: 'hero-di-inject-additional-dsl',
|
||||
template: '<hero-title-dsl title="Tour of Heroes"></hero-title-dsl>'
|
||||
}).Class({
|
||||
constructor: function HeroDIInjectAdditionalDslComponent() { }
|
||||
});
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
|
|
@ -1,58 +1,41 @@
|
|||
(function(app) {
|
||||
|
||||
// #docregion parameters
|
||||
function HeroComponent(name) {
|
||||
this.name = name;
|
||||
}
|
||||
HeroComponent.parameters = [
|
||||
'heroName'
|
||||
];
|
||||
HeroComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-di-inject',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
];
|
||||
// #enddocregion parameters
|
||||
// #docregion
|
||||
app.HeroDIInjectComponent = HeroDIInjectComponent;
|
||||
|
||||
app.HeroesDIInjectModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
providers: [ { provide: 'heroName', useValue: 'Windstorm' } ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
(function(app) {
|
||||
// #docregion ctor
|
||||
var HeroComponent = ng.core.Component({
|
||||
selector: 'hero-di-inline2',
|
||||
HeroDIInjectComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-di-inject',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
new ng.core.Inject('heroName'),
|
||||
function(name) {
|
||||
this.name = name;
|
||||
}
|
||||
]
|
||||
});
|
||||
// #enddocregion ctor
|
||||
];
|
||||
|
||||
app.HeroesDIInjectModule2 =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
providers: [ { provide: 'heroName', useValue: 'Bombasto' } ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
HeroDIInjectComponent.parameters = [ 'heroName' ];
|
||||
|
||||
function HeroDIInjectComponent(name) {
|
||||
this.name = name;
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
/////// DSL version ////////
|
||||
|
||||
(function(app) {
|
||||
|
||||
// #docregion dsl
|
||||
app.HeroDIInjectDslComponent = ng.core.Component({
|
||||
selector: 'hero-di-inject-dsl',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
new ng.core.Inject('heroName'),
|
||||
function HeroDIInjectDslComponent(name) {
|
||||
this.name = name;
|
||||
}
|
||||
]
|
||||
});
|
||||
// #enddocregion dsl
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
(function(app) {
|
||||
// #docregion
|
||||
var HeroComponent = ng.core.Component({
|
||||
selector: 'hero-di-inline',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
app.DataService,
|
||||
function(service) {
|
||||
this.name = service.getHeroName();
|
||||
}
|
||||
]
|
||||
});
|
||||
// #enddocregion
|
||||
|
||||
app.HeroDIInlineModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
providers: [ app.DataService ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
|
||||
})(window.app = window.app || {});
|
|
@ -1,33 +1,43 @@
|
|||
(function(app) {
|
||||
|
||||
// #docregion
|
||||
app.HeroDIComponent = HeroComponent;
|
||||
|
||||
function HeroComponent(dataService) {
|
||||
this.name = dataService.getHeroName();
|
||||
}
|
||||
|
||||
HeroComponent.parameters = [
|
||||
app.DataService
|
||||
];
|
||||
app.HeroDIComponent = HeroDIComponent;
|
||||
|
||||
HeroComponent.annotations = [
|
||||
HeroDIComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-di',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
];
|
||||
|
||||
HeroDIComponent.parameters = [ app.DataService ];
|
||||
|
||||
function HeroDIComponent(dataService) {
|
||||
this.name = dataService.getHeroName();
|
||||
}
|
||||
|
||||
// #enddocregion
|
||||
|
||||
app.HeroesDIModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
providers: [ app.DataService ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
////// DSL Version /////
|
||||
|
||||
(function(app) {
|
||||
|
||||
// #docregion dsl
|
||||
app.HeroDIDslComponent = ng.core.Component({
|
||||
selector: 'hero-di-dsl',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
app.DataService,
|
||||
function HeroDIDslComponent(service) {
|
||||
this.name = service.getHeroName();
|
||||
}
|
||||
]
|
||||
});
|
||||
// #enddocregion dsl
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
// #docplaster
|
||||
// #docregion appexport
|
||||
(function(app) {
|
||||
|
||||
// #docregion component
|
||||
var HeroComponent = ng.core.Component({
|
||||
selector: 'hero-view-2',
|
||||
template: '<h1>{{title}}: {{getName()}}</h1>',
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {
|
||||
this.title = "Hero Detail";
|
||||
},
|
||||
getName: function() { return 'Windstorm'; }
|
||||
});
|
||||
// #enddocregion component
|
||||
|
||||
app.HeroesDslModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
|
||||
})(window.app = window.app || {});
|
||||
// #enddocregion appexport
|
|
@ -0,0 +1,97 @@
|
|||
(function(app) {
|
||||
|
||||
// #docregion
|
||||
app.HeroHostComponent = HeroHostComponent;
|
||||
|
||||
HeroHostComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-host',
|
||||
template:
|
||||
'<h1 [class.active]="active">Hero Host</h1>' +
|
||||
'<div>Heading clicks: {{clicks}}</div>',
|
||||
host: {
|
||||
// HostBindings to the <hero-host> element
|
||||
'[title]': 'title',
|
||||
'[class.heading]': 'headingClass',
|
||||
'(click)': 'clicked()',
|
||||
|
||||
// HostListeners on the entire <hero-host> element
|
||||
'(mouseenter)': 'enter($event)',
|
||||
'(mouseleave)': 'leave($event)'
|
||||
},
|
||||
// Styles within (but excluding) the <hero-host> element
|
||||
styles: ['.active {background-color: yellow;}']
|
||||
})
|
||||
];
|
||||
|
||||
function HeroHostComponent() {
|
||||
this.clicks = 0;
|
||||
this.headingClass = true;
|
||||
this.title = 'Hero Host Tooltip content';
|
||||
}
|
||||
|
||||
HeroHostComponent.prototype.clicked = function() {
|
||||
this.clicks += 1;
|
||||
}
|
||||
|
||||
HeroHostComponent.prototype.enter = function(event) {
|
||||
this.active = true;
|
||||
this.headingClass = false;
|
||||
}
|
||||
|
||||
HeroHostComponent.prototype.leave = function(event) {
|
||||
this.active = false;
|
||||
this.headingClass = true;
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
//// DSL Version ////
|
||||
|
||||
(function(app) {
|
||||
|
||||
// #docregion dsl
|
||||
app.HeroHostDslComponent = ng.core.Component({
|
||||
selector: 'hero-host-dsl',
|
||||
template: `
|
||||
<h1 [class.active]="active">Hero Host (DSL)</h1>
|
||||
<div>Heading clicks: {{clicks}}</div>
|
||||
`,
|
||||
host: {
|
||||
// HostBindings to the <hero-host-dsl> element
|
||||
'[title]': 'title',
|
||||
'[class.heading]': 'headingClass',
|
||||
'(click)': 'clicked()',
|
||||
|
||||
// HostListeners on the entire <hero-host-dsl> element
|
||||
'(mouseenter)': 'enter($event)',
|
||||
'(mouseleave)': 'leave($event)'
|
||||
},
|
||||
// Styles within (but excluding) the <hero-host-dsl> element
|
||||
styles: ['.active {background-color: coral;}']
|
||||
})
|
||||
.Class({
|
||||
constructor: function HeroHostDslComponent() {
|
||||
this.clicks = 0;
|
||||
this.headingClass = true;
|
||||
this.title = 'Hero Host Tooltip DSL content';
|
||||
},
|
||||
|
||||
clicked() {
|
||||
this.clicks += 1;
|
||||
},
|
||||
|
||||
enter(event) {
|
||||
this.active = true;
|
||||
this.headingClass = false;
|
||||
},
|
||||
|
||||
leave(event) {
|
||||
this.active = false;
|
||||
this.headingClass = true;
|
||||
}
|
||||
});
|
||||
// #enddocregion dsl
|
||||
|
||||
})(window.app = window.app || {});
|
|
@ -0,0 +1,7 @@
|
|||
<app-confirm-dsl [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</app-confirm-dsl>
|
||||
<span *ngIf="okClicked">OK clicked</span>
|
||||
<span *ngIf="cancelClicked">Cancel clicked</span>
|
|
@ -0,0 +1,7 @@
|
|||
<app-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</app-confirm>
|
||||
<span *ngIf="okClicked">OK clicked</span>
|
||||
<span *ngIf="cancelClicked">Cancel clicked</span>
|
|
@ -1,62 +1,42 @@
|
|||
(function(app) {
|
||||
// #docregion
|
||||
var ConfirmComponent = ng.core.Component({
|
||||
selector: 'my-confirm',
|
||||
templateUrl: 'app/confirm.component.html',
|
||||
inputs: [
|
||||
'okMsg',
|
||||
'notOkMsg: cancelMsg'
|
||||
],
|
||||
outputs: [
|
||||
'ok',
|
||||
'notOk: cancel'
|
||||
]
|
||||
}).Class({
|
||||
constructor: function() {
|
||||
this.ok = new ng.core.EventEmitter();
|
||||
this.notOk = new ng.core.EventEmitter();
|
||||
},
|
||||
onOkClick: function() {
|
||||
this.ok.next(true);
|
||||
},
|
||||
onNotOkClick: function() {
|
||||
this.notOk.next(true);
|
||||
}
|
||||
});
|
||||
// #enddocregion
|
||||
|
||||
function AppComponent() {
|
||||
}
|
||||
AppComponent.annotations = [
|
||||
new ng.core.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>'
|
||||
})
|
||||
];
|
||||
AppComponent.prototype.onOk = function() {
|
||||
this.okClicked = true;
|
||||
}
|
||||
AppComponent.prototype.onCancel = function() {
|
||||
this.cancelClicked = true;
|
||||
}
|
||||
app.HeroIOComponent = HeroComponent;
|
||||
|
||||
app.HeroesIOModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ConfirmComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
HeroComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-io',
|
||||
templateUrl: 'app/hero-io.component.html'
|
||||
})
|
||||
];
|
||||
|
||||
function HeroComponent() { }
|
||||
|
||||
HeroComponent.prototype.onOk = function() {
|
||||
this.okClicked = true;
|
||||
}
|
||||
|
||||
HeroComponent.prototype.onCancel = function() {
|
||||
this.cancelClicked = true;
|
||||
}
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
///// DSL Version ////
|
||||
|
||||
(function(app) {
|
||||
|
||||
app.HeroIODslComponent = ng.core.Component({
|
||||
selector: 'hero-io-dsl',
|
||||
templateUrl: 'app/hero-io-dsl.component.html'
|
||||
})
|
||||
.Class({
|
||||
constructor: function HeroIODslComponent() { },
|
||||
onOk: function() {
|
||||
this.okClicked = true;
|
||||
},
|
||||
onCancel: function() {
|
||||
this.cancelClicked = true;
|
||||
}
|
||||
});
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
|
|
@ -1,28 +1,42 @@
|
|||
// #docplaster
|
||||
(function(app) {
|
||||
// #docregion
|
||||
function HeroComponent() {}
|
||||
// #enddocregion
|
||||
HeroComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-lifecycle',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
];
|
||||
// #docregion
|
||||
HeroComponent.prototype.ngOnInit = function() {
|
||||
this.name = 'Windstorm';
|
||||
};
|
||||
// #enddocregion
|
||||
|
||||
app.HeroesLifecycleModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
// #docregion
|
||||
app.HeroLifecycleComponent = HeroComponent;
|
||||
|
||||
HeroComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-lifecycle',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
];
|
||||
|
||||
function HeroComponent() { }
|
||||
|
||||
HeroComponent.prototype.ngOnInit = function() {
|
||||
// todo: fetch from server async
|
||||
setTimeout(() => this.name = 'Windstorm', 0);
|
||||
};
|
||||
// #enddocregion
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
/////// DSL version ////
|
||||
|
||||
(function(app) {
|
||||
|
||||
// #docregion dsl
|
||||
app.HeroLifecycleDslComponent = ng.core.Component({
|
||||
selector: 'hero-lifecycle-dsl',
|
||||
template: '<h1>Hero: {{name}}</h1>'
|
||||
})
|
||||
.Class({
|
||||
constructor: function HeroLifecycleDslComponent() { },
|
||||
ngOnInit: function() {
|
||||
// todo: fetch from server async
|
||||
setTimeout(() => this.name = 'Windstorm', 0);
|
||||
}
|
||||
});
|
||||
// #enddocregion dsl
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
(function(app) {
|
||||
|
||||
app.heroQueries = app.heroQueries || {};
|
||||
|
||||
app.heroQueries.ContentChildComponent = ng.core.Component({
|
||||
selector: 'content-child',
|
||||
template:
|
||||
'<span class="content-child" *ngIf="active">' +
|
||||
'Active' +
|
||||
'</span>'
|
||||
}).Class({
|
||||
constructor: function ContentChildComponent() {
|
||||
this.active = false;
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
this.active = !this.active;
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////
|
||||
|
||||
// #docregion content
|
||||
app.heroQueries.ViewChildComponent = ng.core.Component({
|
||||
selector: 'view-child',
|
||||
template:
|
||||
'<h2 [class.active]=active>' +
|
||||
'{{hero.name}} ' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</h2>',
|
||||
styles: ['.active {font-weight: bold; background-color: skyblue;}'],
|
||||
inputs: ['hero'],
|
||||
queries: {
|
||||
content: new ng.core.ContentChild(app.heroQueries.ContentChildComponent)
|
||||
}
|
||||
})
|
||||
.Class({
|
||||
constructor: function HeroQueriesHeroComponent() {
|
||||
this.active = false;
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
this.active = !this.active;
|
||||
this.content.activate();
|
||||
}
|
||||
});
|
||||
// #enddocregion content
|
||||
|
||||
////////////////////
|
||||
|
||||
// #docregion view
|
||||
app.heroQueries.HeroQueriesComponent = ng.core.Component({
|
||||
selector: 'hero-queries',
|
||||
template:
|
||||
'<view-child *ngFor="let hero of heroData" [hero]="hero">' +
|
||||
'<content-child></content-child>' +
|
||||
'</view-child>' +
|
||||
'<button (click)="activate()">{{buttonLabel}} All</button>',
|
||||
queries: {
|
||||
views: new ng.core.ViewChildren(app.heroQueries.ViewChildComponent)
|
||||
}
|
||||
})
|
||||
.Class({
|
||||
constructor: function HeroQueriesComponent() {
|
||||
this.active = false;
|
||||
this.heroData = [
|
||||
{id: 1, name: 'Windstorm'},
|
||||
{id: 2, name: 'LaughingGas'}
|
||||
];
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
this.active = !this.active;
|
||||
this.views.forEach(function(view) {
|
||||
view.activate();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// #docregion defined-property
|
||||
// add prototype property w/ getter outside the DSL
|
||||
var proto = app.heroQueries.HeroQueriesComponent.prototype;
|
||||
Object.defineProperty(proto, "buttonLabel", {
|
||||
get: function () {
|
||||
return this.active ? 'Deactivate' : 'Activate';
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
// #enddocregion defined-property
|
||||
// #enddocregion view
|
||||
|
||||
})(window.app = window.app || {});
|
|
@ -1,3 +1,4 @@
|
|||
<!-- #docregion -->
|
||||
<h1>{{titlePrefix}} {{title}}</h1>
|
||||
<button (click)="ok()">OK</button>
|
||||
<p>{{ msg }}</p>
|
|
@ -0,0 +1,60 @@
|
|||
(function(app) {
|
||||
|
||||
// #docregion
|
||||
app.HeroTitleComponent = HeroTitleComponent;
|
||||
|
||||
// #docregion templateUrl
|
||||
HeroTitleComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-title',
|
||||
templateUrl: 'app/hero-title.component.html'
|
||||
})
|
||||
];
|
||||
// #enddocregion templateUrl
|
||||
|
||||
function HeroTitleComponent(titlePrefix, title) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
this.msg = '';
|
||||
}
|
||||
|
||||
HeroTitleComponent.prototype.ok = function() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
|
||||
HeroTitleComponent.parameters = [
|
||||
[new ng.core.Optional(), new ng.core.Inject('titlePrefix')],
|
||||
[new ng.core.Attribute('title')]
|
||||
];
|
||||
|
||||
// #enddocregion
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
////////// DSL version ////////////
|
||||
|
||||
(function(app) {
|
||||
|
||||
// #docregion dsl
|
||||
app.HeroTitleDslComponent = ng.core.Component({
|
||||
selector: 'hero-title-dsl',
|
||||
templateUrl: 'app/hero-title.component.html'
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
[ new ng.core.Optional(), new ng.core.Inject('titlePrefix') ],
|
||||
new ng.core.Attribute('title'),
|
||||
function HeroTitleDslComponent(titlePrefix, title) {
|
||||
this.titlePrefix = titlePrefix;
|
||||
this.title = title;
|
||||
this.msg = '';
|
||||
}
|
||||
],
|
||||
|
||||
ok: function() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
});
|
||||
// #enddocregion dsl
|
||||
|
||||
})(window.app = window.app || {});
|
|
@ -1,38 +1,48 @@
|
|||
// #docplaster
|
||||
// #docregion appexport
|
||||
(function(app) {
|
||||
// #enddocregion appexport
|
||||
|
||||
// #docregion metadata
|
||||
// #docregion appexport
|
||||
// #docregion constructorproto
|
||||
function HeroComponent() {
|
||||
this.title = "Hero Detail";
|
||||
}
|
||||
HeroComponent.prototype.getName = function() { return 'Windstorm'; };
|
||||
// #enddocregion constructorproto
|
||||
// #docregion
|
||||
// #docregion appexport
|
||||
// #docregion metadata
|
||||
app.HeroComponent = HeroComponent; // "export"
|
||||
|
||||
// #enddocregion appexport
|
||||
HeroComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-view',
|
||||
template: '<h1>{{title}}: {{getName()}}</h1>'
|
||||
})
|
||||
];
|
||||
// #enddocregion metadata
|
||||
HeroComponent.annotations = [
|
||||
new ng.core.Component({
|
||||
selector: 'hero-view',
|
||||
template: '<h1>{{title}}: {{getName()}}</h1>'
|
||||
})
|
||||
];
|
||||
|
||||
app.HeroesModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
// #docregion constructorproto
|
||||
function HeroComponent() {
|
||||
this.title = "Hero Detail";
|
||||
}
|
||||
|
||||
// #docregion appexport
|
||||
app.HeroComponent = HeroComponent;
|
||||
HeroComponent.prototype.getName = function() { return 'Windstorm'; };
|
||||
// #enddocregion constructorproto
|
||||
|
||||
// #enddocregion metadata
|
||||
// #enddocregion appexport
|
||||
// #enddocregion
|
||||
|
||||
})(window.app = window.app || {});
|
||||
|
||||
//////////// DSL version ///////////
|
||||
|
||||
(function(app) {
|
||||
|
||||
// #docregion dsl
|
||||
app.HeroDslComponent = ng.core.Component({
|
||||
selector: 'hero-view-dsl',
|
||||
template: '<h1>{{title}}: {{getName()}}</h1>',
|
||||
})
|
||||
.Class({
|
||||
constructor: function HeroDslComponent() {
|
||||
this.title = "Hero Detail";
|
||||
},
|
||||
|
||||
getName: function() { return 'Windstorm'; }
|
||||
});
|
||||
// #enddocregion dsl
|
||||
|
||||
})(window.app = window.app || {});
|
||||
// #enddocregion appexport
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
(function(app) {
|
||||
|
||||
// #docregion
|
||||
var HeroesComponent = ng.core.Component({
|
||||
selector: 'heroes-bindings',
|
||||
template: '<h1 [class.active]="active">' +
|
||||
'Tour of Heroes' +
|
||||
'</h1>',
|
||||
host: {
|
||||
'[title]': 'title',
|
||||
'[class.heading]': 'hClass',
|
||||
'(click)': 'clicked()',
|
||||
'(dblclick)': 'doubleClicked($event)'
|
||||
}
|
||||
}).Class({
|
||||
constructor: function() {
|
||||
this.title = 'Tooltip content';
|
||||
this.hClass = true;
|
||||
},
|
||||
clicked: function() {
|
||||
this.active = !this.active;
|
||||
},
|
||||
doubleClicked: function(evt) {
|
||||
this.active = true;
|
||||
}
|
||||
});
|
||||
// #enddocregion
|
||||
|
||||
app.HeroesHostBindingsModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
declarations: [ HeroesComponent ],
|
||||
bootstrap: [ HeroesComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
|
||||
})(window.app = window.app || {});
|
|
@ -1,82 +0,0 @@
|
|||
(function(app) {
|
||||
|
||||
var ActiveLabelComponent = ng.core.Component({
|
||||
selector: 'active-label',
|
||||
template: '<span class="active-label"' +
|
||||
'*ngIf="active">' +
|
||||
'Active' +
|
||||
'</span>'
|
||||
}).Class({
|
||||
constructor: [function() { }],
|
||||
activate: function() {
|
||||
this.active = true;
|
||||
}
|
||||
});
|
||||
|
||||
// #docregion content
|
||||
var HeroComponent = ng.core.Component({
|
||||
selector: 'a-hero',
|
||||
template: '<h2 [class.active]=active>' +
|
||||
'{{hero.name}} ' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</h2>',
|
||||
inputs: ['hero'],
|
||||
queries: {
|
||||
label: new ng.core.ContentChild(
|
||||
ActiveLabelComponent)
|
||||
}
|
||||
}).Class({
|
||||
constructor: [function() { }],
|
||||
activate: function() {
|
||||
this.active = true;
|
||||
this.label.activate();
|
||||
}
|
||||
});
|
||||
app.HeroQueriesComponent = HeroComponent;
|
||||
// #enddocregion content
|
||||
|
||||
// #docregion view
|
||||
var AppComponent = ng.core.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 ng.core.ViewChildren(
|
||||
HeroComponent)
|
||||
}
|
||||
}).Class({
|
||||
constructor: function() {
|
||||
this.heroData = [
|
||||
{id: 1, name: 'Windstorm'},
|
||||
{id: 2, name: 'Superman'}
|
||||
];
|
||||
},
|
||||
activate: function() {
|
||||
this.heroCmps.forEach(function(cmp) {
|
||||
cmp.activate();
|
||||
});
|
||||
}
|
||||
});
|
||||
// #enddocregion view
|
||||
|
||||
app.HeroesQueriesModule =
|
||||
ng.core.NgModule({
|
||||
imports: [ ng.platformBrowser.BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HeroComponent,
|
||||
ActiveLabelComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {}
|
||||
});
|
||||
|
||||
})(window.app = window.app || {});
|
|
@ -1,32 +1,9 @@
|
|||
// #docplaster
|
||||
// #docregion appimport
|
||||
(function(app) {
|
||||
// #enddocregion appimport
|
||||
|
||||
// #docregion ng2import
|
||||
var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic;
|
||||
var LocationStrategy = ng.common.LocationStrategy;
|
||||
var HashLocationStrategy = ng.common.HashLocationStrategy;
|
||||
// #enddocregion ng2import
|
||||
var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic;
|
||||
|
||||
// #docregion appimport
|
||||
var HeroComponent = app.HeroComponent;
|
||||
// #enddocregion appimport
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
platformBrowserDynamic().bootstrapModule(app.AppModule);
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesDslModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesLifecycleModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesDIModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroDIInlineModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesDIInjectModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesDIInjectModule2);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesDIInjectAdditionalModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesIOModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesHostBindingsModule);
|
||||
platformBrowserDynamic().bootstrapModule(app.HeroesQueriesModule);
|
||||
});
|
||||
|
||||
// #docregion appimport
|
||||
})(window.app = window.app || {});
|
||||
// #enddocregion appimport
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<title>TypeScript to JavaScript</title>
|
||||
|
||||
<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>
|
||||
|
||||
<!-- Angular and RxJS umd scripts -->
|
||||
<script src="node_modules/rxjs/bundles/Rx.js"></script>
|
||||
<script src="node_modules/@angular/core/bundles/core.umd.js"></script>
|
||||
<script src="node_modules/@angular/common/bundles/common.umd.js"></script>
|
||||
|
@ -17,50 +19,26 @@
|
|||
<script src="node_modules/@angular/platform-browser/bundles/platform-browser.umd.js"></script>
|
||||
<script src="node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"></script>
|
||||
|
||||
<!-- Application scripts -->
|
||||
<script src="app/app.component.js"></script>
|
||||
<script src="app/confirm.component.js"></script>
|
||||
<script src="app/data.service.js"></script>
|
||||
<script src="app/hero.component.js"></script>
|
||||
<script src="app/hero-dsl.component.js"></script>
|
||||
<script src="app/hero-lifecycle.component.js"></script>
|
||||
<script src="app/hero-io.component.js"></script>
|
||||
<script src="app/hero-di.component.js"></script>
|
||||
<script src="app/hero-di-inline.component.js"></script>
|
||||
<script src="app/hero-di-inject.component.js"></script>
|
||||
<script src="app/hero-di-inject-additional.component.js"></script>
|
||||
<script src="app/heroes-bindings.component.js"></script>
|
||||
<script src="app/heroes-queries.component.js"></script>
|
||||
<script src="app/hero-host.component.js"></script>
|
||||
<script src="app/hero-lifecycle.component.js"></script>
|
||||
<script src="app/hero-queries.component.js"></script>
|
||||
<script src="app/hero-title.component.js"></script>
|
||||
|
||||
<script src="app/app.module.js"></script>
|
||||
<script src="app/main.js"></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>Loading hero-view...</hero-view>
|
||||
<hero-view-2>Loading hero-view2...</hero-view-2>
|
||||
<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-inline>Loading hero-di-inline...</hero-di-inline>
|
||||
<hero-di-inline2>Loading hero-di-inline2...</hero-di-inline2>
|
||||
<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>Loading heroes-queries...</heroes-queries>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<a id="toc"></a>
|
||||
<h1>{{title}}</h1>
|
||||
<a href="#class-metadata">Classes and Class Metadata</a><br>
|
||||
<a href="#io-metadata">Input and Output Decorators</a><br>
|
||||
<a href="#dependency-injection">Dependency Injection</a><br>
|
||||
<a href="#host-metadata">Host Metadata</a><br>
|
||||
<a href="#view-child-metadata">View and Child Metadata</a><br>
|
||||
|
||||
<hr>
|
||||
<h4 id="class-metadata">Classes and Class Metadata</h4>
|
||||
<hero-view></hero-view>
|
||||
<hero-lifecycle></hero-lifecycle>
|
||||
|
||||
<hr>
|
||||
<h4 id="io-metadata">Input and Output Metadata</h4>
|
||||
<hero-io></hero-io>
|
||||
|
||||
<hr>
|
||||
<h4 id="dependency-injection">Dependency Injection</h4>
|
||||
<hero-di></hero-di>
|
||||
<hero-di-inject></hero-di-inject>
|
||||
<hero-di-inject-additional></hero-di-inject-additional>
|
||||
|
||||
<hr>
|
||||
<h4 id="host-metadata">Host Metadata</h4>
|
||||
<hero-host></hero-host>
|
||||
<hero-host-meta></hero-host-meta>
|
||||
|
||||
<hr>
|
||||
<h4 id="view-child-metadata">View and Child Metadata</h4>
|
||||
<hero-queries></hero-queries>
|
|
@ -0,0 +1,15 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'my-app',
|
||||
templateUrl: 'app.component.html',
|
||||
styles: [
|
||||
// See hero-di-inject-additional.component
|
||||
'hero-host, hero-host-meta { border: 1px dashed black; display: block; padding: 4px;}',
|
||||
'.heading {font-style: italic}'
|
||||
]
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'TypeScript';
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/* tslint:disable-next-line:no-unused-variable */
|
||||
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { ConfirmComponent } from './confirm.component';
|
||||
// #docregion appimport
|
||||
import { HeroComponent } from './hero.component';
|
||||
// #enddocregion appimport
|
||||
import { HeroComponent as HeroDIComponent } from './hero-di.component';
|
||||
import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component';
|
||||
import { HeroComponent as HeroDIInjectAdditionalComponent } from './hero-di-inject-additional.component';
|
||||
import { HeroHostComponent } from './hero-host.component';
|
||||
import { HeroHostMetaComponent } from './hero-host-meta.component';
|
||||
import { HeroIOComponent } from './hero-io.component';
|
||||
import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component';
|
||||
import { HeroQueriesComponent, ViewChildComponent, ContentChildComponent } from './hero-queries.component';
|
||||
import { HeroTitleComponent } from './hero-title.component';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ConfirmComponent,
|
||||
HeroComponent,
|
||||
HeroDIComponent,
|
||||
HeroDIInjectComponent,
|
||||
HeroDIInjectAdditionalComponent,
|
||||
HeroHostComponent, HeroHostMetaComponent,
|
||||
HeroIOComponent,
|
||||
HeroLifecycleComponent,
|
||||
HeroQueriesComponent, ViewChildComponent, ContentChildComponent,
|
||||
HeroTitleComponent
|
||||
],
|
||||
providers: [
|
||||
DataService,
|
||||
{ provide: 'heroName', useValue: 'Windstorm' }
|
||||
],
|
||||
bootstrap: [ AppComponent ],
|
||||
|
||||
// schemas: [ NO_ERRORS_SCHEMA ] // helpful for debugging!
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
/* tslint:disable no-unused-variable */
|
||||
// #docregion ng2import
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import {
|
||||
LocationStrategy,
|
||||
HashLocationStrategy
|
||||
} from '@angular/common';
|
||||
// #enddocregion ng2import
|
|
@ -0,0 +1,22 @@
|
|||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'app-confirm',
|
||||
templateUrl: 'confirm.component.html'
|
||||
})
|
||||
export class ConfirmComponent {
|
||||
@Input() okMsg = '';
|
||||
@Input('cancelMsg') notOkMsg = '';
|
||||
@Output() ok = new EventEmitter();
|
||||
@Output('cancel') notOk = new EventEmitter();
|
||||
|
||||
onOkClick() {
|
||||
this.ok.emit(true);
|
||||
}
|
||||
onNotOkClick() {
|
||||
this.notOk.emit(true);
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
|
@ -2,8 +2,8 @@ import { Injectable } from '@angular/core';
|
|||
|
||||
@Injectable()
|
||||
export class DataService {
|
||||
constructor() {
|
||||
}
|
||||
constructor() { }
|
||||
|
||||
getHeroName() {
|
||||
return 'Windstorm';
|
||||
}
|
||||
|
|
|
@ -1,46 +1,7 @@
|
|||
import {
|
||||
Attribute,
|
||||
Component,
|
||||
Inject,
|
||||
Optional,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
// #docregion metadata
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'hero-title',
|
||||
templateUrl: 'title.component.html'
|
||||
})
|
||||
// #enddocregion metadata
|
||||
class TitleComponent {
|
||||
private msg: string = '';
|
||||
constructor(
|
||||
@Inject('titlePrefix') @Optional() private titlePrefix: string,
|
||||
@Attribute('title') private title: string
|
||||
) { }
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hero-di-inject-additional',
|
||||
template: `<hero-title title="Tour of Heroes">
|
||||
</hero-title>`
|
||||
template: `<hero-title title="Tour of Heroes"></hero-title>`
|
||||
})
|
||||
class AppComponent { }
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TitleComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class HeroesDIInjectAdditionalModule { }
|
||||
export class HeroComponent { }
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
import { Component, Inject, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-di-inject',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
class HeroComponent {
|
||||
export class HeroComponent {
|
||||
constructor(@Inject('heroName') private name: string) { }
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
providers: [ { provide: 'heroName', useValue: 'Windstorm' } ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesDIInjectModule { }
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import { Component, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { DataService } from './data.service';
|
||||
|
||||
// #docregion
|
||||
|
@ -8,19 +6,10 @@ import { DataService } from './data.service';
|
|||
selector: 'hero-di',
|
||||
template: `<h1>Hero: {{name}}</h1>`
|
||||
})
|
||||
|
||||
class HeroComponent {
|
||||
name: string;
|
||||
export 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,44 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-host-meta',
|
||||
template: `
|
||||
<h1 [class.active]="active">Hero Host in Metadata</h1>
|
||||
<div>Heading clicks: {{clicks}}</div>
|
||||
`,
|
||||
host: {
|
||||
// HostBindings to the <hero-host-meta> element
|
||||
'[title]': 'title',
|
||||
'[class.heading]': 'headingClass',
|
||||
|
||||
// HostListeners on the entire <hero-host-meta> element
|
||||
'(click)': 'clicked()',
|
||||
'(mouseenter)': 'enter($event)',
|
||||
'(mouseleave)': 'leave($event)'
|
||||
},
|
||||
// Styles within (but excluding) the <hero-host-meta> element
|
||||
styles: ['.active {background-color: coral;}']
|
||||
})
|
||||
export class HeroHostMetaComponent {
|
||||
title = 'Hero Host in Metadata Tooltip';
|
||||
headingClass = true;
|
||||
|
||||
active = false;
|
||||
clicks = 0;
|
||||
|
||||
clicked() {
|
||||
this.clicks += 1;
|
||||
}
|
||||
|
||||
enter(event: Event) {
|
||||
this.active = true;
|
||||
this.headingClass = false;
|
||||
}
|
||||
|
||||
leave(event: Event) {
|
||||
this.active = false;
|
||||
this.headingClass = true;
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
|
@ -0,0 +1,39 @@
|
|||
import { Component, HostBinding, HostListener } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'hero-host',
|
||||
template: `
|
||||
<h1 [class.active]="active">Hero Host in Decorators</h1>
|
||||
<div>Heading clicks: {{clicks}}</div>
|
||||
`,
|
||||
// Styles within (but excluding) the <hero-host> element
|
||||
styles: ['.active {background-color: yellow;}']
|
||||
})
|
||||
export class HeroHostComponent {
|
||||
// HostBindings to the <hero-host> element
|
||||
@HostBinding() title = 'Hero Host in Decorators Tooltip';
|
||||
@HostBinding('class.heading') headingClass = true;
|
||||
|
||||
active = false;
|
||||
clicks = 0;
|
||||
|
||||
// HostListeners on the entire <hero-host> element
|
||||
@HostListener('click')
|
||||
clicked() {
|
||||
this.clicks += 1;
|
||||
}
|
||||
|
||||
@HostListener('mouseenter', ['$event'])
|
||||
enter(event: Event) {
|
||||
this.active = true;
|
||||
this.headingClass = false;
|
||||
}
|
||||
|
||||
@HostListener('mouseleave', ['$event'])
|
||||
leave(event: Event) {
|
||||
this.active = false;
|
||||
this.headingClass = true;
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
|
@ -1,67 +1,26 @@
|
|||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'my-confirm',
|
||||
templateUrl: 'confirm.component.html'
|
||||
})
|
||||
class ConfirmComponent {
|
||||
@Input() okMsg: string;
|
||||
@Input('cancelMsg') notOkMsg: string;
|
||||
@Output() ok =
|
||||
new EventEmitter();
|
||||
@Output('cancel') notOk =
|
||||
new EventEmitter();
|
||||
|
||||
onOkClick() {
|
||||
this.ok.next(true);
|
||||
}
|
||||
onNotOkClick() {
|
||||
this.notOk.next(true);
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hero-io',
|
||||
template: `
|
||||
<my-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</my-confirm>
|
||||
<app-confirm [okMsg]="'OK'"
|
||||
[cancelMsg]="'Cancel'"
|
||||
(ok)="onOk()"
|
||||
(cancel)="onCancel()">
|
||||
</app-confirm>
|
||||
<span *ngIf="okClicked">OK clicked</span>
|
||||
<span *ngIf="cancelClicked">Cancel clicked</span>
|
||||
`
|
||||
})
|
||||
class AppComponent {
|
||||
okClicked: boolean;
|
||||
cancelClicked: boolean;
|
||||
export class HeroIOComponent {
|
||||
okClicked = false;
|
||||
cancelClicked = false;
|
||||
|
||||
onOk() {
|
||||
this.okClicked = true;
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
this.cancelClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ConfirmComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class HeroesIOModule { }
|
||||
|
|
|
@ -1,27 +1,14 @@
|
|||
// #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 implements OnInit {
|
||||
export class HeroComponent implements OnInit {
|
||||
name: string;
|
||||
ngOnInit() {
|
||||
this.name = 'Windstorm';
|
||||
// todo: fetch from server async
|
||||
setTimeout(() => this.name = 'Windstorm', 0);
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesLifecycleModule { }
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
import {
|
||||
Component,
|
||||
ContentChild,
|
||||
Input,
|
||||
QueryList,
|
||||
ViewChildren
|
||||
} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'content-child',
|
||||
template: `
|
||||
<span class="content-child" *ngIf="active">
|
||||
Active
|
||||
</span>`
|
||||
})
|
||||
export class ContentChildComponent {
|
||||
active = false;
|
||||
|
||||
activate() {
|
||||
this.active = !this.active;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
// #docregion content
|
||||
@Component({
|
||||
selector: 'view-child',
|
||||
template: `
|
||||
<h2 [class.active]=active>
|
||||
{{hero.name}}
|
||||
<ng-content></ng-content>
|
||||
</h2>`,
|
||||
styles: ['.active {font-weight: bold; background-color: skyblue;}']
|
||||
})
|
||||
export class ViewChildComponent {
|
||||
@Input() hero: any;
|
||||
active = false;
|
||||
|
||||
@ContentChild(ContentChildComponent) content: ContentChildComponent;
|
||||
|
||||
activate() {
|
||||
this.active = !this.active;
|
||||
this.content.activate();
|
||||
}
|
||||
}
|
||||
// #enddocregion content
|
||||
|
||||
////////////////////
|
||||
|
||||
// #docregion view
|
||||
@Component({
|
||||
selector: 'hero-queries',
|
||||
template: `
|
||||
<view-child *ngFor="let hero of heroData" [hero]="hero">
|
||||
<content-child></content-child>
|
||||
</view-child>
|
||||
<button (click)="activate()">{{buttonLabel}} All</button>
|
||||
`
|
||||
})
|
||||
export class HeroQueriesComponent {
|
||||
active = false;
|
||||
heroData = [
|
||||
{id: 1, name: 'Windstorm'},
|
||||
{id: 2, name: 'LaughingGas'}
|
||||
];
|
||||
|
||||
@ViewChildren(ViewChildComponent) views: QueryList<ViewChildComponent>;
|
||||
|
||||
activate() {
|
||||
this.active = !this.active;
|
||||
this.views.forEach(
|
||||
view => view.activate()
|
||||
);
|
||||
}
|
||||
|
||||
// #docregion defined-property
|
||||
get buttonLabel() {
|
||||
return this.active ? 'Deactivate' : 'Activate';
|
||||
}
|
||||
// #enddocregion defined-property
|
||||
}
|
||||
// #enddocregion view
|
|
@ -1,3 +1,4 @@
|
|||
<!-- #docregion -->
|
||||
<h1>{{titlePrefix}} {{title}}</h1>
|
||||
<button (click)="ok()">OK</button>
|
||||
<p>{{ msg }}</p>
|
|
@ -0,0 +1,22 @@
|
|||
import { Attribute, Component, Inject, Optional } from '@angular/core';
|
||||
|
||||
// #docregion
|
||||
// #docregion templateUrl
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'hero-title',
|
||||
templateUrl: 'hero-title.component.html'
|
||||
})
|
||||
// #enddocregion templateUrl
|
||||
export class HeroTitleComponent {
|
||||
msg: string = '';
|
||||
constructor(
|
||||
@Inject('titlePrefix') @Optional() private titlePrefix: string,
|
||||
@Attribute('title') private title: string
|
||||
) { }
|
||||
|
||||
ok() {
|
||||
this.msg = 'OK!';
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
|
@ -1,4 +1,3 @@
|
|||
// #docplaster
|
||||
// #docregion metadata
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
|
@ -6,24 +5,10 @@ import { Component } from '@angular/core';
|
|||
selector: 'hero-view',
|
||||
template: '<h1>{{title}}: {{getName()}}</h1>'
|
||||
})
|
||||
// #docregion appexport
|
||||
// #docregion class
|
||||
// #docregion appexport, class
|
||||
export class HeroComponent {
|
||||
title = 'Hero Detail';
|
||||
getName() {return 'Windstorm'; }
|
||||
}
|
||||
// #enddocregion class
|
||||
// #enddocregion appexport
|
||||
// #enddocregion appexport, class
|
||||
// #enddocregion metadata
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroComponent ],
|
||||
bootstrap: [ HeroComponent ]
|
||||
})
|
||||
export class HeroesModule { }
|
||||
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
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: boolean;
|
||||
|
||||
constructor() {}
|
||||
|
||||
@HostListener('click')
|
||||
clicked() {
|
||||
this.active = !this.active;
|
||||
}
|
||||
|
||||
@HostListener('dblclick', ['$event'])
|
||||
doubleClicked(evt: Event) {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ HeroesComponent ],
|
||||
bootstrap: [ HeroesComponent ]
|
||||
})
|
||||
export class HeroesHostBindingsModule { }
|
|
@ -1,88 +0,0 @@
|
|||
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: boolean;
|
||||
|
||||
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: any;
|
||||
active: boolean;
|
||||
|
||||
@ContentChild(ActiveLabelComponent)
|
||||
label: ActiveLabelComponent;
|
||||
|
||||
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: QueryList<HeroComponent>;
|
||||
|
||||
activate() {
|
||||
this.heroCmps.forEach(
|
||||
(cmp) => cmp.activate()
|
||||
);
|
||||
}
|
||||
}
|
||||
// #enddocregion view
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [
|
||||
HeroesQueriesComponent,
|
||||
HeroComponent,
|
||||
ActiveLabelComponent
|
||||
],
|
||||
bootstrap: [ HeroesQueriesComponent ]
|
||||
})
|
||||
export class HeroesQueriesModule { }
|
|
@ -1,30 +1,4 @@
|
|||
/* 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);
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<title>TypeScript to JavaScript</title>
|
||||
|
||||
<!-- Polyfills for older browsers -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
@ -20,32 +21,7 @@
|
|||
</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>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -15,19 +15,16 @@ a#toc
|
|||
:marked
|
||||
## Table of contents
|
||||
|
||||
[_TypeScript_ to _ES6_ to _ES5_](#from-ts)
|
||||
|
||||
[Modularity: imports and exports](#modularity)
|
||||
|
||||
[Classes and Class Metadata](#class-metadata)
|
||||
|
||||
[Input and Output Metadata](#property-metadata)
|
||||
|
||||
[Dependency Injection](#dependency-injection)
|
||||
|
||||
[Host and Query Metadata](#host-query-metadata)
|
||||
|
||||
[AoT compilation in _TypeScript_ Only](#aot)
|
||||
[_TypeScript_ to _ES6_ to _ES5_](#from-ts)<br>
|
||||
[Modularity: imports and exports](#modularity)<br>
|
||||
[Classes and Class Metadata](#class-metadata)<br>
|
||||
[_ES5_ DSL](#dsl)<br>
|
||||
[Interfaces](#interfaces)<br>
|
||||
[Input and Output Metadata](#io-decorators)<br>
|
||||
[Dependency Injection](#dependency-injection)<br>
|
||||
[Host Binding](#host-binding)<br>
|
||||
[View and Child Decorators](#view-child-decorators)<br>
|
||||
[AoT compilation in _TypeScript_ Only](#aot)<br>
|
||||
|
||||
**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.**
|
||||
|
@ -38,7 +35,7 @@ a#from-ts
|
|||
## _TypeScript_ to _ES6_ to _ES5_
|
||||
|
||||
_TypeScript_
|
||||
<a href="https://www._TypeScript_lang.org" target="_blank" title='"TypeScript is a typed, superset of JavaScript"'>is a typed superset of _ES6 JavaScript_</a>.
|
||||
<a href="https://www.typescriptlang.org" target="_blank" title='"TypeScript is a typed, superset of JavaScript"'>is a typed superset of _ES6 JavaScript_</a>.
|
||||
_ES6 JavaScript_ is a superset of _ES5 JavaScript_. _ES5_ is the kind of JavaScript that runs natively in all modern browsers.
|
||||
The transformation of _TypeScript_ code all the way down to _ES5_ code can be seen as "shedding" features.
|
||||
|
||||
|
@ -48,17 +45,17 @@ a#from-ts
|
|||
* _ES6-without-decorators_ to _ES5_
|
||||
|
||||
When translating from _TypeScript_ to _ES6-with-decorators_, remove
|
||||
[class property access modifiers](http://www._TypeScript_lang.org/docs/handbook/classes.html#public-private-and-protected-modifiers)
|
||||
[class property access modifiers](http://www.typescriptlang.org/docs/handbook/classes.html#public-private-and-protected-modifiers)
|
||||
such as `public` and `private`.
|
||||
Remove most of the
|
||||
[type annotations](https://www._TypeScript_lang.org/docs/handbook/basic-types.html),
|
||||
such as `string` and `boolean`
|
||||
but **keep type annotations used for dependency injection**.
|
||||
[type declarations](https://www.typescriptlang.org/docs/handbook/basic-types.html),
|
||||
such as `:string` and `:boolean`
|
||||
but **keep the constructor parameter types which are used for dependency injection**.
|
||||
|
||||
|
||||
From _ES6-with-decorators_ to _plain ES6_, remove all
|
||||
[decorators](https://www._TypeScript_lang.org/docs/handbook/decorators.html)
|
||||
and the remaining type annotations.
|
||||
[decorators](https://www.typescriptlang.org/docs/handbook/decorators.html)
|
||||
and the remaining types.
|
||||
You must declare properties in the class constructor (`this.title = '...'`) rather than in the body of the class.
|
||||
|
||||
Finally, from _plain ES6_ to _ES5_, the main missing features are `import`
|
||||
|
@ -82,24 +79,20 @@ a#modularity
|
|||
|
||||
In _ES5_, you access the Angular entities of the [the Angular packages](../glossary.html#!#scoped-package)
|
||||
through the global `ng` object.
|
||||
Everything you would have imported from `@angular` is a nested member of this `ng` object:
|
||||
Anything you can import from `@angular` is a nested member of this `ng` object:
|
||||
|
||||
+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,
|
||||
cb-ts-to-js/ts/app/app.module.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/app.module.es6,
|
||||
cb-ts-to-js/js-es6/app/app.module.es6,
|
||||
cb-ts-to-js/js/app/app.module.js
|
||||
`,
|
||||
'ng2import,ng2import,ng2import,ng2import',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
`)(format='.')
|
||||
|
||||
:marked
|
||||
### Exporting Application Code
|
||||
|
@ -118,9 +111,9 @@ a#modularity
|
|||
Add one application namespace object such as `app` to the global `document`.
|
||||
Then each code file "exports" public entities by attaching them to that namespace object, e.g., `app.HeroComponent`.
|
||||
You could factor a large application into several sub-namespaces
|
||||
which leads to "exports" along the lines of `app.heroes.HeroComponent`.
|
||||
which leads to "exports" along the lines of `app.heroQueries.HeroComponent`.
|
||||
|
||||
Every file should wrap _ES5_ code in an
|
||||
Every _ES5_ file should wrap code in an
|
||||
[Immediately Invoked Function Expression (IIFE)](https://en.wikipedia.org/wiki/Immediately-invoked_function_expression)
|
||||
to limit unintentional leaking of private symbols into the global scope.
|
||||
|
||||
|
@ -131,13 +124,9 @@ a#modularity
|
|||
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,
|
||||
`,
|
||||
'appexport,appexport,appexport,appexport',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
|
@ -151,17 +140,13 @@ a#modularity
|
|||
In _ES5_ you use the shared namespace object to access "exported" entities from other files.
|
||||
|
||||
+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,
|
||||
cb-ts-to-js/ts/app/app.module.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/app.module.es6,
|
||||
cb-ts-to-js/js-es6/app/app.module.es6,
|
||||
cb-ts-to-js/js/app/app.module.js
|
||||
`,
|
||||
'appimport,appimport,appimport,appimport',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
|
@ -183,6 +168,20 @@ a#class-metadata
|
|||
### Classes
|
||||
|
||||
Most Angular _TypeScript_ and _ES6_ code is written as classes.
|
||||
|
||||
Properties and method parameters of _TypeScript_ classes may be marked with the access modifiers
|
||||
`private`, `internal`, and `public`.
|
||||
Remove these modifiers when translating to JavaScript.
|
||||
|
||||
Most type declarations (e.g, `:string` and `:boolean`) should be removed when translating to JavaScript.
|
||||
When translating to _ES6-with-decorators_, ***do not remove types from constructor parameters!***
|
||||
|
||||
Look for types in _TypeScript_ property declarations.
|
||||
In general it is better to initialize such properties with default values because
|
||||
many browser JavaScript engines can generate more performant code.
|
||||
When _TypeScript_ code follows this same advice, it can infer the property types
|
||||
and there is nothing to remove during translation.
|
||||
|
||||
In _ES6-without-decorators_, properties of classes must be assigned inside the constructor.
|
||||
|
||||
_ES5_ JavaScript has no classes.
|
||||
|
@ -193,13 +192,9 @@ a#class-metadata
|
|||
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,
|
||||
`,
|
||||
'class,class,class,constructorproto',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
|
@ -226,13 +221,9 @@ a#class-metadata
|
|||
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
|
||||
`,`
|
||||
metadata,
|
||||
metadata,
|
||||
metadata,
|
||||
metadata
|
||||
`,`
|
||||
TypeScript,
|
||||
`,
|
||||
'metadata,metadata,metadata,metadata',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
|
@ -242,62 +233,95 @@ a#class-metadata
|
|||
***External Template file***
|
||||
|
||||
A large component template is often kept in a separate template file.
|
||||
+makeExample('cb-ts-to-js/ts/app/title.component.html', '', 'app/title.component.html')(format='.')
|
||||
+makeExample('cb-ts-to-js/ts/app/hero-title.component.html', '', 'app/hero-title.component.html')(format='.')
|
||||
:marked
|
||||
The component (`TitleComponent` in this case) then references the template file in its metadata `templateUrl` property:
|
||||
The component (`HeroTitleComponent` in this case) then references the template file in its metadata `templateUrl` property:
|
||||
+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`,
|
||||
'metadata, metadata, metadata, metadata',
|
||||
cb-ts-to-js/ts/app/hero-title.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-title.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-title.component.es6,
|
||||
cb-ts-to-js/js/app/hero-title.component.js`,
|
||||
'templateUrl, templateUrl, templateUrl, templateUrl',
|
||||
`TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript`)(format='.')
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)(format='.')
|
||||
|
||||
:marked
|
||||
Note that the _TypeScript_ and both _ES6_ file `templateUrl` properties identify the location of the template file _relative to the component module_.
|
||||
Note that the _TypeScript_ and both _ES6_ `templateUrl` properties identify the location of the template file _relative to the component module_.
|
||||
All three metadata configurations specify the `moduleId` property
|
||||
so that Angular can calculate the proper module address.
|
||||
.l-sub-section
|
||||
:marked
|
||||
The `moduleId` may not be needed with certain tooling but it's safest to provide it anyway.
|
||||
:marked
|
||||
|
||||
The _ES5_ approach shown here does not support modules and therefore there is no way to calculate a _module-relative URL_.
|
||||
The `templateUrl` for the _ES5_ code must specify the _path from the project root_ and
|
||||
omits the irrelevant `moduleId` property.
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
With the right tooling, the `moduleId` may not be needed in the other JavaScript dialects either.
|
||||
But it's safest to provide it anyway.
|
||||
|
||||
***Angular class API***
|
||||
a#dsl
|
||||
.l-main-section
|
||||
:marked
|
||||
## _ES5_ DSL
|
||||
|
||||
This _ES5_ pattern of creating a constructor and annotating it with metadata is so common that Angular
|
||||
provides a convenience API to make it a little more compact and locates the metadata above the constructor,
|
||||
as you would if you wrote in _TypeScript_ or _ES6-with-decorators_.
|
||||
|
||||
Set a component variable to the result of an `ng.core.Component` function call.
|
||||
This _API_ (_Application Programming Interface_) is commonly known as the _ES5 DSL_ (_Domain Specific Language_).
|
||||
|
||||
Set an application namespace property (e.g., `app.HeroDslComponent`) to the result of an `ng.core.Component` function call.
|
||||
Pass the same metadata object to `ng.core.Component` as you did before.
|
||||
|
||||
Then chain a call to the `Class` method which takes an object defining the class constructor and instance methods.
|
||||
|
||||
Here is an example of the component class API next to the annotated function version for comparison:
|
||||
Here is an example of the `HeroComponent`, re-written with the DSL,
|
||||
next to the original _ES5_ version for comparison:
|
||||
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/js/app/hero-dsl.component.js,
|
||||
cb-ts-to-js/js/app/hero.component.js,
|
||||
cb-ts-to-js/js/app/hero.component.js
|
||||
`,`
|
||||
component,
|
||||
metadata
|
||||
`,`
|
||||
ES5 JavaScript with Class API,
|
||||
`,
|
||||
'dsl,',
|
||||
`
|
||||
ES5 JavaScript with DSL,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
|
||||
.callout.is-helpful
|
||||
header Name the constructor
|
||||
:marked
|
||||
A **named** constructor displays clearly in the console log
|
||||
if the component throws a runtime error.
|
||||
An **unnamed** constructor displays as an anonymous function (e.g., `class0`)
|
||||
which is impossible to find in the source code.
|
||||
|
||||
:marked
|
||||
There are similar APIs for other decorated classes.
|
||||
### Properties with getters and setters
|
||||
|
||||
_TypeScript_ and _ES6_ support with getters and setters.
|
||||
Here's an example of a read-only _TypeScript_ property with a getter
|
||||
that prepares a toggle-button label for the next clicked state:
|
||||
+makeExample('cb-ts-to-js/ts/app/hero-queries.component.ts', 'defined-property', 'ts/app/hero-queries.component.ts')(format='.')
|
||||
|
||||
:marked
|
||||
This _TypeScript_ "getter" property is transpiled to an _ES5_
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"
|
||||
target="_blank" title="Defined Properties">defined property</a>.
|
||||
The _ES5 DSL_ does not support _defined properties_ directly
|
||||
but you can still create them by extracting the "class" prototype and
|
||||
adding the _defined property_ in raw JavaScript like this:
|
||||
+makeExample('cb-ts-to-js/js/app/hero-queries.component.js', 'defined-property','js/app/hero-queries.component.ts')(format='.')
|
||||
|
||||
:marked
|
||||
### DSL for other classes
|
||||
There are similar DSLs for other decorated classes.
|
||||
You can define a directive with `ng.core.Directive`:
|
||||
|
||||
code-example.
|
||||
var MyDirective = ng.core.Directive({
|
||||
app.MyDirective = ng.core.Directive({
|
||||
selector: '[myDirective]'
|
||||
}).Class({
|
||||
...
|
||||
|
@ -305,18 +329,20 @@ code-example.
|
|||
:marked
|
||||
and a pipe with `ng.core.Pipe`:
|
||||
code-example.
|
||||
var MyPipe = ng.core.Pipe({
|
||||
app.MyPipe = ng.core.Pipe({
|
||||
name: 'myPipe'
|
||||
}).Class({
|
||||
...
|
||||
});
|
||||
|
||||
a#interfaces
|
||||
.l-main-section
|
||||
:marked
|
||||
### Interfaces
|
||||
## Interfaces
|
||||
|
||||
A _TypeScript_ interface helps ensure that a class implements the interface's members correctly.
|
||||
We strongly recommend Angular interfaces where appropriate.
|
||||
For example, a component that implements the `ngOnInit` lifecycle hook method
|
||||
For example, the component class that implements the `ngOnInit` lifecycle hook method
|
||||
should implement the `OnInit` interface.
|
||||
|
||||
_TypeScript_ interfaces exist for developer convenience and are not used by Angular at runtime.
|
||||
|
@ -327,16 +353,18 @@ code-example.
|
|||
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,
|
||||
cb-ts-to-js/js/app/hero-lifecycle.component.js
|
||||
`,`
|
||||
`,`
|
||||
TypeScript,
|
||||
`,
|
||||
',,,,dsl',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with DSL
|
||||
`)
|
||||
|
||||
a#property-metadata
|
||||
a#io-decorators
|
||||
.l-main-section
|
||||
:marked
|
||||
## Input and Output Metadata
|
||||
|
@ -357,16 +385,18 @@ a#property-metadata
|
|||
combined in the metadata `inputs` and `outputs` _arrays_.
|
||||
|
||||
+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,
|
||||
cb-ts-to-js/ts/app/confirm.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/confirm.component.es6,
|
||||
cb-ts-to-js/js-es6/app/confirm.component.es6,
|
||||
cb-ts-to-js/js/app/confirm.component.js,
|
||||
cb-ts-to-js/js/app/confirm.component.js
|
||||
`,
|
||||
',,,,dsl',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with DSL
|
||||
`)
|
||||
:marked
|
||||
In the previous example, one of the public-facing binding names (`cancelMsg`)
|
||||
|
@ -376,53 +406,76 @@ a#property-metadata
|
|||
|
||||
In _TypeScript_ and _ES6-with-decorators_,
|
||||
you specify the special binding name in the argument to the property decorator.
|
||||
|
||||
In _ES5_ and _plain ES6_ code, convey this pairing with the `propertyName: bindingName` syntax in the class metadata.
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Dependency Injection
|
||||
Angular relies heavily on [Dependency Injection](../guide/dependency-injection.html) to provide services to the objects it creates.
|
||||
When Angular creates a new component, directive, pipe or another service,
|
||||
it sets the class constructor parameters to instances of services provided by an _Injector_.
|
||||
|
||||
### Injection by Type
|
||||
The developer must tell Angular what to inject into each parameter.
|
||||
|
||||
Angular can often use _TypeScript_ type information to determine what needs to be injected.
|
||||
_ES6-with-decorators_ can also make use of type information.
|
||||
### Injection by Class Type
|
||||
|
||||
Since no type information is available in _ES5_/_ES6_ JavaScript, you must identify "injectables" in
|
||||
some other way.
|
||||
|
||||
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.
|
||||
The easiest and most popular technique in _TypeScript_ and _ES6-with-decorators_ is to set the constructor parameter type
|
||||
to the class associated with the service to inject.
|
||||
|
||||
In _ES6_ the decorators need to be inside a nested array.
|
||||
When writing in the _ES5_ class convenience API, you can supply the parameter tokens by wrapping
|
||||
the constructor in an array.
|
||||
The _TypeScript_ transpiler writes parameter type information into the generated JavaScript.
|
||||
Angular reads that information at runtime and locates the corresponding service in the appropriate _Injector_..
|
||||
The _ES6-with-decorators_ transpiler does essentially the same thing using the same parameter-typing syntax.
|
||||
|
||||
_ES5_ and _plain ES6_ lack types so you must identify "injectables" by attaching a **`parameters`** array to the constructor function.
|
||||
Each item in the array specifies the service's injection token.
|
||||
|
||||
As with _TypeScript_ the most popular token is a class,
|
||||
or rather a _constructor function_ that represents a class in _ES5_ and _plain ES6_.
|
||||
The format of the `parameters` array varies:
|
||||
|
||||
* _plain ES6_ — nest each constructor function in a sub-array.
|
||||
|
||||
* _ES5_ — simply list the constructor functions.
|
||||
|
||||
When writing with _ES5 DSL_, set the `Class.constructor` property to
|
||||
an array whose first parameters are the injectable constructor functions and whose
|
||||
last parameter is the class constructor itself.
|
||||
This format should be familiar to Angular 1 developers.
|
||||
|
||||
+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,
|
||||
cb-ts-to-js/js/app/hero-di.component.js
|
||||
`,
|
||||
',,,,dsl',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with Class API
|
||||
ES5 JavaScript with DSL
|
||||
`)
|
||||
|
||||
:marked
|
||||
### Injection with the @Inject decorator
|
||||
|
||||
When the thing being injected doesn't correspond directly to a type, you use the
|
||||
`@Inject()` decorator to supply the injection token.
|
||||
In this example, you are injecting a string identified by the "heroName" token.
|
||||
Sometimes the dependency injection token isn't a class or constructor function.
|
||||
|
||||
In _TypeScript_ and _ES6-with-decorators_, you precede the class constructor parameter
|
||||
by calling the `@Inject()` decorator with the injection token.
|
||||
In the following example, the token is the string `'heroName'`.
|
||||
|
||||
In _ES5_/_ES6_ JavaScript you add the token string to the injection parameters array.
|
||||
Alternatively, when using the _ES5_ convenience class API you can create a token with the
|
||||
`Inject` method and add that to the constructor array in the annotations.
|
||||
The other JavaScript dialogs add a `parameters` array to the class contructor function.
|
||||
Each item constains a new instance of `Inject('heroName')`:
|
||||
|
||||
* _plain ES6_ — each item is a new instance of `Inject(token)` in a sub-array.
|
||||
|
||||
* _ES5_ — simply list the string tokens.
|
||||
|
||||
When writing with _ES5 DSL_, set the `Class.constructor` property to a function definition
|
||||
array as before. Create a `new ng.core.Inject(token)` for each parameter.
|
||||
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero-di-inject.component.ts,
|
||||
|
@ -430,67 +483,74 @@ a#property-metadata
|
|||
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,
|
||||
`,
|
||||
',,,,dsl',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with Class API
|
||||
ES5 JavaScript with DSL
|
||||
`)
|
||||
|
||||
:marked
|
||||
### Additional Injection Decorators
|
||||
|
||||
You can attach additional decorators to constructor parameters to qualify the injection behavior.
|
||||
You 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)).
|
||||
You can qualify injection behavior with injection decorators from `@angular/core`.
|
||||
|
||||
In ES6 JavaScript you just add the extra decorators to the nested injection parameters array.
|
||||
In _TypeScript_ and _ES6-with-decorators_,
|
||||
you precede the constructor parameters with injection qualifiers such as:
|
||||
* [`@Optional`](../api/core/index/Optional-decorator.html) sets the parameter to `null` if the service is missing
|
||||
* [`@Attribute`](../api/core/index/Attribute-interface.html) to inject a host element attribute value
|
||||
* [`@ContentChild`](../api/core/index/ContentChild-decorator.html) to inject a content child
|
||||
* [`@ViewChild`](../api/core/index/ViewChild-decorator.html) to inject a view child
|
||||
* [`@Host`](../api/core/index/Host-decorator.html) to inject a service in this component or its host
|
||||
* [`@SkipSelf`](../api/core/index/SkipSelf-decorator.html) to inject a service provided in an ancestor of this component
|
||||
|
||||
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.
|
||||
In _plain ES6_ and _ES5_, create an instance of the equivalent injection qualifier in a nested array within the `parameters` array.
|
||||
For example, you'd write `new Optional()` in _plain ES6_ and `new ng.core.Optional()` in _ES5_.
|
||||
|
||||
You 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.
|
||||
|
||||
When writing with _ES5 DSL_, set the `Class.constructor` property to a function definition
|
||||
array as before. Use a nested array to define a parameter's complete injection specification.
|
||||
|
||||
+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,
|
||||
cb-ts-to-js/ts/app/hero-title.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-title.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-title.component.es6,
|
||||
cb-ts-to-js/js/app/hero-title.component.js,
|
||||
cb-ts-to-js/js/app/hero-title.component.js
|
||||
`,
|
||||
',,,,dsl',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
`)
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with DSL
|
||||
`)
|
||||
.l-sub-section
|
||||
:marked
|
||||
In the example above, there is no provider for the `'titlePrefix'` token.
|
||||
Without `Optional`, Angular would raise an error.
|
||||
With `Optional`, Angular sets the constructor parameter to `null`
|
||||
and the component displays the title without a prefix.
|
||||
|
||||
a#host-query-metadata
|
||||
a#host-binding
|
||||
.l-main-section
|
||||
:marked
|
||||
## Host and Query Metadata
|
||||
## Host Binding
|
||||
Angular supports bindings to properties and events of the _host element_ which is the
|
||||
element whose tag matches the component selector.
|
||||
|
||||
### Host Decorators
|
||||
|
||||
In _TypeScript_ and _ES6-with-decorators_ you can use host property decorators to bind a host
|
||||
In _TypeScript_ and _ES6-with-decorators_, you 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_/_ES6_, add a `host` attribute to the component metadata to achieve the
|
||||
In _plain ES6_ or _ES5_, 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:
|
||||
|
@ -500,54 +560,74 @@ a#host-query-metadata
|
|||
* Each value identifies the corresponding component property or method.
|
||||
|
||||
+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,
|
||||
cb-ts-to-js/ts/app/hero-host.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-host.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-host.component.es6,
|
||||
cb-ts-to-js/js/app/hero-host.component.js,
|
||||
cb-ts-to-js/js/app/hero-host.component.js
|
||||
`,
|
||||
',,,,dsl',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
ES5 JavaScript,
|
||||
ES5 JavaScript with DSL
|
||||
`)
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
In _TypeScript_ and _ES6-with-decorators_ you can also use the `queries` metadata
|
||||
instead of the `@ViewChild` and `@ContentChild` property decorators.
|
||||
|
||||
:marked
|
||||
### Query Decorators
|
||||
### Host Metadata
|
||||
Some developers prefer to specify host properties and listeners
|
||||
in the component metadata.
|
||||
They'd _rather_ do it the way you _must_ do it _ES5_ and _plain ES6_.
|
||||
|
||||
The following re-implementation of the `HeroComponent` reminds us that _any property metadata decorator_
|
||||
can be expressed as component or directive metadata in both _TypeScript_ and _ES6-with-decorators_.
|
||||
These particular _TypeScript_ and _ES6_ code snippets happen to be identical.
|
||||
+makeTabs(`
|
||||
cb-ts-to-js/ts/app/hero-host-meta.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-host-meta.component.es6
|
||||
`,
|
||||
'',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators
|
||||
`)
|
||||
|
||||
a#view-child-decorators
|
||||
.l-main-section
|
||||
:marked
|
||||
### View and Child Decorators
|
||||
|
||||
There are several property decorators for querying the descendants of
|
||||
a component or directive.
|
||||
Several _property_ decorators query a component's nested view and content components.
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
_View_ children are associated with element tags that appear _within_ the component's template.
|
||||
|
||||
_Content_ children are associated with elements that appear _between_ the component's element tags;
|
||||
they are projected into an `<ng-content>` slot in the component's template.
|
||||
:marked
|
||||
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.
|
||||
|
||||
In _ES5_/_ES6_ JavaScript you 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`.
|
||||
In _ES5_ and _ES6_, you access a component's view children by adding a `queries` property to the component metadata.
|
||||
The `queries` property value is a hash map.
|
||||
|
||||
* each _key_ is the name of a component property that will hold the view child or children.
|
||||
* each _value_ is a new instance of either `ViewChild` or `ViewChildren`.
|
||||
|
||||
+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,
|
||||
cb-ts-to-js/ts/app/hero-queries.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-queries.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-queries.component.es6,
|
||||
cb-ts-to-js/js/app/hero-queries.component.js
|
||||
`,
|
||||
'view, view, view, view',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
ES5 JavaScript with DSL
|
||||
`)
|
||||
|
||||
:marked
|
||||
|
@ -560,22 +640,23 @@ a#host-query-metadata
|
|||
[`@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,
|
||||
cb-ts-to-js/ts/app/hero-queries.component.ts,
|
||||
cb-ts-to-js/js-es6-decorators/app/hero-queries.component.es6,
|
||||
cb-ts-to-js/js-es6/app/hero-queries.component.es6,
|
||||
cb-ts-to-js/js/app/hero-queries.component.js
|
||||
`,
|
||||
'content, content, content, content',
|
||||
` TypeScript,
|
||||
ES6 JavaScript with decorators,
|
||||
ES6 JavaScript,
|
||||
ES5 JavaScript
|
||||
ES5 JavaScript with DSL
|
||||
`)
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
In _TypeScript_ and _ES6-with-decorators_ you can also use the `queries` metadata
|
||||
instead of the `@ViewChild` and `@ContentChild` property decorators.
|
||||
|
||||
a#aot
|
||||
.l-main-section
|
||||
:marked
|
||||
|
|
Loading…
Reference in New Issue