diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.ts
index ee5a414e1a..ec5dadc4a0 100644
--- a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.ts
+++ b/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.ts
@@ -1,22 +1,23 @@
-// #docplaster
-// #docregion
import { Component, OnInit } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
-import { Hero } from './shared';
+import { Hero, HeroService } from './shared';
// #docregion example
@Component({
- // #enddocregion example
moduleId: module.id,
- // #docregion example
selector: 'toh-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
- heroes: Hero[];
+ heroes: Observable;
selectedHero: Hero;
- ngOnInit() { }
+ constructor(private heroService: HeroService) { }
+
+ ngOnInit() {
+ this.heroes = this.heroService.getHeroes();
+ }
}
// #enddocregion example
diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/hero.service.ts
new file mode 100644
index 0000000000..80e1d97455
--- /dev/null
+++ b/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/hero.service.ts
@@ -0,0 +1,18 @@
+import { Injectable } from '@angular/core';
+import { Http } from '@angular/http';
+
+import { Observable } from 'rxjs/Observable';
+import 'rxjs/add/operator/map';
+
+import { Hero } from './hero.model';
+
+@Injectable()
+export class HeroService {
+
+ constructor(private http: Http) {}
+
+ getHeroes(): Observable {
+ return this.http.get('api/heroes')
+ .map(resp => resp.json().data as Hero[]);
+ }
+}
diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/index.ts
index 0dceb684c4..dbb150d3f8 100644
--- a/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/index.ts
+++ b/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/index.ts
@@ -1 +1,2 @@
export * from './hero.model';
+export * from './hero.service';
diff --git a/public/docs/_examples/style-guide/ts/05-13/app/app.component.html b/public/docs/_examples/style-guide/ts/05-13/app/app.component.html
index 094f24b258..3cd94ca772 100644
--- a/public/docs/_examples/style-guide/ts/05-13/app/app.component.html
+++ b/public/docs/_examples/style-guide/ts/05-13/app/app.component.html
@@ -1,3 +1,6 @@
+
+
+
The Great Bombasto
diff --git a/public/docs/_examples/style-guide/ts/05-13/app/app.module.ts b/public/docs/_examples/style-guide/ts/05-13/app/app.module.ts
index 102ed0f617..7ebe91dbbc 100644
--- a/public/docs/_examples/style-guide/ts/05-13/app/app.module.ts
+++ b/public/docs/_examples/style-guide/ts/05-13/app/app.module.ts
@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
-import { HeroButtonComponent } from './heroes';
+import { HeroButtonComponent, HeroHighlightDirective } from './heroes';
@NgModule({
imports: [
@@ -10,7 +10,7 @@ import { HeroButtonComponent } from './heroes';
],
declarations: [
AppComponent,
- HeroButtonComponent
+ HeroButtonComponent, HeroHighlightDirective
],
exports: [ AppComponent ]
})
diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts
index 9724ad437d..4e67a14113 100644
--- a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts
+++ b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts
@@ -1,13 +1,13 @@
-// #docregion
import { Component, EventEmitter, Input, Output } from '@angular/core';
// #docregion example
-/* avoid */
+/* avoid pointless aliasing */
@Component({
selector: 'toh-hero-button',
template: ``
})
export class HeroButtonComponent {
+ // Pointless aliases
@Output('changeEvent') change = new EventEmitter();
@Input('labelAttribute') label: string;
}
diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.ts
index b299740765..af6e7d46b7 100644
--- a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.ts
+++ b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.ts
@@ -7,6 +7,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
template: ``
})
export class HeroButtonComponent {
+ // No aliases
@Output() change = new EventEmitter();
@Input() label: string;
}
diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-highlight.directive.ts b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-highlight.directive.ts
new file mode 100644
index 0000000000..f9e76248a8
--- /dev/null
+++ b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-highlight.directive.ts
@@ -0,0 +1,15 @@
+// #docregion
+import { Directive, ElementRef, Input, OnChanges } from '@angular/core';
+
+@Directive({ selector: '[heroHighlight]' })
+export class HeroHighlightDirective implements OnChanges {
+
+ // Aliased because `color` is a better property name than `heroHighlight`
+ @Input('heroHighlight') color: string;
+
+ constructor(private el: ElementRef) {}
+
+ ngOnChanges() {
+ this.el.nativeElement.style.backgroundColor = this.color || 'yellow';
+ }
+}
diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/index.ts
index 2334d49c9a..565f46cf4f 100644
--- a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/index.ts
+++ b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/index.ts
@@ -1 +1,2 @@
export * from './hero-button';
+export * from './hero-highlight.directive';
diff --git a/public/docs/ts/latest/guide/style-guide.jade b/public/docs/ts/latest/guide/style-guide.jade
index 2a9e52b935..3d34dad65a 100644
--- a/public/docs/ts/latest/guide/style-guide.jade
+++ b/public/docs/ts/latest/guide/style-guide.jade
@@ -11,7 +11,7 @@ include ../_util-fns
.l-main-section
:marked
- ## Style Vocabulary
+ ## Style vocabulary
Each guideline describes either a good or bad practice, and all have a consistent presentation.
@@ -35,7 +35,7 @@ include ../_util-fns
.l-main-section
:marked
- ## File Structure Conventions
+ ## File structure conventions
Some code examples display a file that has one or more similarly named companion files.
For example, `hero.component.ts` and `hero.component.html`.
@@ -46,7 +46,7 @@ include ../_util-fns
a(id='toc')
:marked
- ## Table of Contents
+ ## Table of contents
1. [Single responsibility](#single-responsibility)
1. [Naming](#naming)
@@ -61,12 +61,14 @@ a(id='toc')
.l-main-section
:marked
- ## Single Responsibility
+ ## Single responsibility
- Apply the [Single Responsibility Principle (SPR)](https://wikipedia.org/wiki/Single_responsibility_principle) to all components, services, and other symbols.
+ Apply the
+ Single Responsibility Principle (SPR)
+ to all components, services, and other symbols.
This helps make the app cleaner, easier to read and maintain, and more testable.
- ### Rule of One
+ ### _Rule of One_
#### Style 01-01
.s-rule.do
:marked
@@ -122,7 +124,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Small Functions
+ ### Small functions
#### Style 01-02
.s-rule.do
:marked
@@ -189,7 +191,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Separate File Names with Dots and Dashes
+ ### Separate file names with dots and dashes
#### Style 02-02
.s-rule.do
@@ -230,7 +232,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Symbols and File Names
+ ### Symbols and file names
#### Style 02-03
.s-rule.do
@@ -336,7 +338,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Service Names
+ ### Service names
#### Style 02-04
.s-rule.do
@@ -434,7 +436,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Directive Selectors
+ ### Directive selectors
#### Style 02-06
.s-rule.do
@@ -453,7 +455,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Custom Prefix for Components
+ ### Custom prefix for components
#### Style 02-07
.s-rule.do
@@ -495,7 +497,7 @@ a(href="#toc") Back to top
:marked
:marked
- ### Custom Prefix for Directives
+ ### Custom prefix for directives
#### Style 02-08
.s-rule.do
@@ -524,7 +526,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Pipe Names
+ ### Pipe names
#### Style 02-09
.s-rule.do
@@ -564,7 +566,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Unit Test File Names
+ ### Unit test file names
#### Style 02-10
.s-rule.do
@@ -628,7 +630,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### End to End Test File Names
+ ### _End-to-End_ (E2E) test file names
#### Style 02-11
.s-rule.do
@@ -667,7 +669,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Angular NgModule Names
+ ### Angular _NgModule_ names
#### Style 02-12
.s-rule.do
@@ -759,7 +761,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ## Coding Conventions
+ ## Coding conventions
Have consistent set of coding, naming, and whitespace conventions.
@@ -881,7 +883,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Properties and Methods
+ ### Properties and methods
#### Style 03-04
.s-rule.do
@@ -914,7 +916,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Import Line Spacing
+ ### Import line spacing
#### Style 03-06
.s-rule.consider
@@ -927,15 +929,15 @@ a(href="#toc") Back to top
.s-rule.consider
:marked
- **Consider** listing destructured imported assets alphabetically.
+ **Consider** listing destructured imported symbols alphabetically.
.s-why
:marked
- **Why?** The empty line makes it easy to read and locate imports.
+ **Why?** The empty line separates _your_ stuff from _their_ stuff.
.s-why.s-why-last
:marked
- **Why?** Alphabetizing makes it easier to read and locate imports.
+ **Why?** Alphabetizing makes it easier to read and locate symbols.
+makeExample('style-guide/ts/03-06/app/heroes/shared/hero.service.avoid.ts', 'example', 'app/heroes/shared/hero.service.ts')(avoid=1)
:marked
@@ -947,7 +949,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ## App Structure and Angular Modules
+ ## Application structure and Angular modules
Have a near-term view of implementation and a long-term vision. Start small but keep in mind where the app is heading down the road.
@@ -963,7 +965,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### LIFT
+ ### _LIFT_
#### Style 04-01
.s-rule.do
@@ -1068,7 +1070,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### T-DRY (Try to be DRY)
+ ### _T-DRY_ (Try to be _DRY_)
#### Style 04-05
.s-rule.do
@@ -1090,7 +1092,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Overall Structural Guidelines
+ ### Overall structural guidelines
#### Style 04-06
.s-rule.do
@@ -1186,7 +1188,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Folders-by-Feature Structure
+ ### _Folders-by-feature_ structure
#### Style 04-07
.s-rule.do
@@ -1230,7 +1232,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### App Root Module
+ ### App _root module_
#### Style 04-08
.s-rule.do
@@ -1256,7 +1258,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Feature Modules
+ ### Feature modules
#### Style 04-09
.s-rule.do
@@ -1303,7 +1305,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Shared Feature Module
+ ### Shared feature module
#### Style 04-10
.s-rule.do
@@ -1400,7 +1402,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Core Feature Module
+ ### Core feature module
#### Style 04-11
.s-rule.consider
@@ -1531,7 +1533,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Prevent Reimport of Core Module
+ ### Prevent re-import of the core module
#### Style 04-12
Only the root `AppModule` should import the `CoreModule`.
@@ -1563,7 +1565,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Lazy Loaded Folders
+ ### Lazy Loaded folders
#### Style 04-13
A distinct application feature or workflow may be *lazy loaded* or *loaded on demand* rather than when the application starts.
@@ -1580,7 +1582,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Never Directly Import Lazy Loaded Folders
+ ### Never directly import lazy loaded folders
#### Style 04-14
.s-rule.avoid
@@ -1597,7 +1599,7 @@ a(href="#toc") Back to top
:marked
## Components
- ### Component Selector Naming
+ ### Component selector names
#### Style 05-02
.s-rule.do
@@ -1623,25 +1625,22 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Components as Elements
+ ### Components as elements
#### Style 05-03
.s-rule.do
:marked
- **Do** define components as elements via the selector.
+ **Do** give components an _element_ selector, as opposed to _attribute_ or _class_ selectors.
.s-why
:marked
- **Why?** components have templates containing HTML and optional Angular template syntax. They are most associated with putting content on a page, and thus are more closely aligned with elements.
-
-.s-why
- :marked
- **Why?** A component represents a visual element on the page.
- Defining the selector as an HTML element tag is consistent with native HTML elements and WebComponents.
+ **Why?** components have templates containing HTML and optional Angular template syntax.
+ They display content.
+ Developers place components on the page as they would native HTML elements and WebComponents.
.s-why.s-why-last
:marked
- **Why?** It is easier to recognize that a symbol is a component vs a directive by looking at the template's html.
+ **Why?** It is easier to recognize that a symbol is a component by looking at the template's html.
+makeExample('style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts', 'example', 'app/heroes/hero-button/hero-button.component.ts')(avoid=1)
:marked
@@ -1661,7 +1660,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Extract Template and Styles to Their Own Files
+ ### Extract templates and styles to their own files
#### Style 05-04
.s-rule.do
@@ -1676,14 +1675,34 @@ a(href="#toc") Back to top
:marked
**Do** name the style file `[component-name].component.css`, where [component-name] is the component name.
+.s-rule.do
+ :marked
+ **Do** specify _component-relative_ URLs, prefixed with `./`, and add `moduleId: module.id` to the component metadata.
+
.s-why
:marked
- **Why?** Syntax hints for inline templates in (*.js and *.ts) code files are not supported by some editors.
+ **Why?** Large, inline templates and styles obscure the component's purpose and implementation, reducing readability and maintainability.
+
+.s-why
+ :marked
+ **Why?** In most editors, syntax hints and code snippets aren't available when developing inline templates and styles.
+ The Angular TypeScript Language Service (forthcoming) promises to overcome this deficiency for HTML templates
+ in those editors that support it; it won't help with CSS styles.
+
+.s-why
+ :marked
+ **Why?** A _component relative_ URL requires no change when you move the component files, as long as the files stay together.
+
+.s-why
+ :marked
+ **Why?** The JIT compiler requires the `moduleId` for relative URLs; the AOT compiler,
+ which doesn't need it, safely ignores this property.
.s-why.s-why-last
:marked
- **Why?** A component file's logic is easier to read when not mixed with inline template and styles.
+ **Why?** The `./` prefix is standard syntax for relative URLs; don't depend on Angular's current ability to do without that prefix.
+
+makeExample('style-guide/ts/05-04/app/heroes/heroes.component.avoid.ts', 'example', 'app/heroes/heroes.component.ts')(avoid=1)
:marked
@@ -1701,17 +1720,17 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Decorate Input and Output Properties Inline
+ ### Decorate _input_ and _output_ properties
#### Style 05-12
.s-rule.do
:marked
- **Do** use `@Input` and `@Output` instead of the `inputs` and `outputs` properties of the
- `@Directive` and `@Component` decorators:
+ **Do** use the `@Input` and `@Output` class decorators instead of the `inputs` and `outputs` properties of the
+ `@Directive` and `@Component` metadata:
.s-rule.do
:marked
- **Do** place the `@Input()` or `@Output()` on the same line as the property they decorate.
+ **Consider** placing `@Input()` or `@Output()` on the same line as the property it decorates.
.s-why
:marked
@@ -1728,7 +1747,8 @@ a(href="#toc") Back to top
.s-why.s-why-last
:marked
- **Why?** Placing the decorator on the same line makes for shorter code and still easily identifies the property as an input or output.
+ **Why?** Placing the decorator on the same line _usually_ makes for shorter code and still easily identifies the property as an input or output.
+ Put it on the line above when doing so is clearly more readable.
+makeExample('style-guide/ts/05-12/app/heroes/shared/hero-button/hero-button.component.avoid.ts', 'example', 'app/heroes/shared/hero-button/hero-button.component.ts')(avoid=1)
:marked
@@ -1740,17 +1760,21 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Avoid Renaming Inputs and Outputs
+ ### Avoid aliasing _inputs_ and _outputs_
#### Style 05-13
.s-rule.avoid
:marked
- **Avoid** renaming inputs and outputs, when possible.
+ **Avoid** _input_ and _output_ aliases except when it serves an important purpose.
+
+.s-why
+ :marked
+ **Why?** Two names for the same property (one private, one public) is inherently confusing.
.s-why.s-why-last
:marked
- **Why?** May lead to confusion when the output or the input
- properties of a given directive are named one way but exported differently as a public API.
+ **Why?** You should use an alias when the directive name is also an _input_ property,
+ and the directive name doesn't describe the property.
+makeExample('style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts', 'example', 'app/heroes/shared/hero-button/hero-button.component.ts')(avoid=1)
:marked
@@ -1760,9 +1784,11 @@ a(href="#toc") Back to top
+makeTabs(
`style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.ts,
+ style-guide/ts/05-13/app/heroes/shared/hero-highlight.directive.ts,
style-guide/ts/05-13/app/app.component.html`,
'example,',
`app/heroes/shared/hero-button/hero-button.component.ts,
+ app/heroes/shared/hero-button/hero-highlight.directive.ts,
app/app.component.html`)
:marked
@@ -1770,7 +1796,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Member Sequence
+ ### Member sequence
#### Style 05-14
.s-rule.do
@@ -1796,7 +1822,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Put Logic in Services
+ ### Delegate complex component logic to services
#### Style 05-15
.s-rule.do
@@ -1833,7 +1859,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Don't Prefix Output Properties
+ ### Don't prefix _output_ properties
#### Style 05-16
.s-rule.do
@@ -1870,7 +1896,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Put Presentation Logic in the Component Class
+ ### Put presentation logic in the component class
#### Style 05-17
.s-rule.do
@@ -1901,7 +1927,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Use Directives to Enhance an Existing Element
+ ### Use directives to enhance an element
#### Style 06-01
.s-rule.do
@@ -1926,7 +1952,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Use HostListener and HostBinding Class Decorators
+ ### _HostListener_/_HostBinding_ decorators versus _host_ metadata
#### Style 06-03
.s-rule.consider
@@ -1962,7 +1988,7 @@ a(href="#toc") Back to top
:marked
## Services
- ### Services are Singletons within an Injector
+ ### Services are singletons
#### Style 07-01
.s-rule.do
@@ -1984,7 +2010,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Single Responsibility
+ ### Single responsibility
#### Style 07-02
.s-rule.do
@@ -2007,7 +2033,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Providing a Service
+ ### Providing a service
#### Style 07-03
.s-rule.do
@@ -2043,7 +2069,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### Use the @Injectable() Class Decorator
+ ### Use the @Injectable() class decorator
#### Style 07-04
.s-rule.do
@@ -2071,7 +2097,7 @@ a(href="#toc") Back to top
:marked
## Data Services
- ### Separate Data Calls
+ ### Talk to the server through a service
#### Style 08-01
.s-rule.do
@@ -2104,15 +2130,15 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ## Lifecycle Hooks
+ ## Lifecycle hooks
- Use Lifecycle Hooks to tap into important events exposed by Angular.
+ Use Lifecycle hooks to tap into important events exposed by Angular.
a(href="#toc") Back to top
.l-main-section
:marked
- ### Implement Lifecycle Hooks Interfaces
+ ### Implement lifecycle hook interfaces
#### Style 09-01
.s-rule.do
@@ -2157,7 +2183,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
- ### File Templates and Snippets
+ ### File templates and snippets
#### Style A-02
.s-rule.do