docs(style-guide): `./` prefix for template/style URLs and other improvements

This commit is contained in:
Ward Bell 2017-01-04 13:59:19 -08:00
parent 4ec1736f18
commit 0056a68ec8
24 changed files with 183 additions and 160 deletions

View File

@ -3,7 +3,7 @@
/* avoid */
import { ExceptionService, SpinnerService, ToastService } from '../../core';
import { Http, Response } from '@angular/http';
import { Http } from '@angular/http';
import { Injectable } from '@angular/core';
import { Hero } from './hero.model';
// #enddocregion example
@ -20,12 +20,12 @@ export class HeroService {
getHero(id: number) {
return this.http.get(`api/heroes/${id}`)
.map((res: Response) => res.json().data);
.map(response => response.json().data as Hero);
}
getHeroes() {
return this.http.get(`api/heroes`)
.map((res: Response) => res.json().data);
.map(response => response.json().data as Hero[]);
}
}

View File

@ -1,7 +1,7 @@
// #docregion
// #docregion example
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Http } from '@angular/http';
import { Hero } from './hero.model';
import { ExceptionService, SpinnerService, ToastService } from '../../core';
@ -20,12 +20,12 @@ export class HeroService {
getHero(id: number) {
return this.http.get(`api/heroes/${id}`)
.map((res: Response) => res.json().data);
.map(response => response.json().data as Hero);
}
getHeroes() {
return this.http.get(`api/heroes`)
.map((res: Response) => res.json().data);
.map(response => response.json().data as Hero[]);
}
}

View File

@ -4,10 +4,10 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
// #enddocregion example
import { RouterModule } from '@angular/router';
import { RouterModule } from '@angular/router';
// #docregion example
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { HeroesComponent } from './heroes/heroes.component';
@NgModule({

View File

@ -1,21 +1,12 @@
// #docplaster
// #docregion
// #docregion example
import { Component, OnInit } from '@angular/core';
@Component({
// #enddocregion example
moduleId: module.id,
// #docregion example
selector: 'toh-heroes',
templateUrl: './heroes.component.html'
})
export class HeroesComponent implements OnInit {
// #enddocregion example
// #docregion example
constructor() { }
constructor() { /* ... */ }
ngOnInit() { }
ngOnInit() { /* ... */ }
}
// #enddocregion example

View File

@ -1,23 +1,14 @@
// #docplaster
// #docregion
// #docregion example
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
import { FilterTextService } from '../shared/filter-text/filter-text.service';
@Component({
// #enddocregion example
moduleId: module.id,
// #docregion example
selector: 'toh-heroes',
templateUrl: './heroes.component.html'
})
export class HeroesComponent implements OnInit {
// #enddocregion example
// #docregion example
filteredHeroes: any[] = [];
constructor(private filterService: FilterTextService) { }
export class HeroesComponent {
heroes = [
{ id: 1, name: 'Windstorm' },
@ -26,13 +17,12 @@ export class HeroesComponent implements OnInit {
{ id: 4, name: 'Tornado' }
];
filteredHeroes = this.heroes;
constructor(private filterService: FilterTextService) { }
filterChanged(searchText: string) {
this.filteredHeroes = this.filterService.filter(searchText, ['id', 'name'], this.heroes);
}
ngOnInit() {
this.filteredHeroes = this.heroes;
}
}
// #enddocregion example

View File

@ -1,21 +1,14 @@
// #docplaster
// #docregion
// #docregion example
import { Component } from '@angular/core';
import { LoggerService } from '../core/logger.service';
import { LoggerService } from '../core/logger.service';
import { SpinnerService } from '../core/spinner/spinner.service';
@Component({
// #enddocregion example
moduleId: module.id,
// #docregion example
selector: 'toh-heroes',
templateUrl: './heroes.component.html'
})
export class HeroesComponent {
// #enddocregion example
// #docregion example
heroes: any[];
constructor(
@ -38,4 +31,3 @@ export class HeroesComponent {
}, 2000);
}
}
// #enddocregion example

View File

@ -1,20 +1,13 @@
// #docplaster
// #docregion
// #docregion example
import { Component } from '@angular/core';
import { LoggerService } from '../core/logger.service';
@Component({
// #enddocregion example
moduleId: module.id,
// #docregion example
selector: 'toh-heroes',
templateUrl: './heroes.component.html'
})
export class HeroesComponent {
// #enddocregion example
// #docregion example
heroes: any[];
constructor(private loggerService: LoggerService) { }
@ -30,4 +23,3 @@ export class HeroesComponent {
this.loggerService.log(`We have ${HeroesComponent.length} heroes`);
}
}
// #enddocregion example

View File

@ -1,13 +1,10 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
// #docregion example
/* avoid */
@Component({
// #enddocregion example
moduleId: module.id,
// #docregion example
selector: 'tohHeroButton',
templateUrl: './hero-button.component.html'
})

View File

@ -1,12 +1,8 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
// #docregion example
@Component({
// #enddocregion example
moduleId: module.id,
// #docregion example
selector: 'toh-hero-button',
templateUrl: './hero-button.component.html'
})

View File

@ -1,13 +1,9 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
// #docregion example
/* avoid */
@Component({
// #enddocregion example
moduleId: module.id,
// #docregion example
selector: '[tohHeroButton]',
templateUrl: './hero-button.component.html'
})

View File

@ -1,12 +1,8 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
// #docregion example
@Component({
// #enddocregion example
moduleId: module.id,
// #docregion example
selector: 'toh-hero-button',
templateUrl: './hero-button.component.html'
})

View File

@ -1,9 +1,10 @@
import { NgModule } from '@angular/core';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { HeroesComponent } from './heroes';
import { HeroService } from './heroes/shared';
@NgModule({
imports: [
@ -14,6 +15,7 @@ import { HeroesComponent } from './heroes';
AppComponent,
HeroesComponent
],
exports: [ AppComponent ]
exports: [ AppComponent ],
providers: [ HeroService ]
})
export class AppModule {}

View File

@ -1,7 +1,8 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Hero, HeroService } from './shared';
import { Hero } from './shared/hero.model';
// #docregion example
/* avoid */
@ -11,7 +12,7 @@ import { Hero } from './shared/hero.model';
<div>
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes">
<li *ngFor="let hero of heroes | async" (click)="selectedHero=hero">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
@ -51,9 +52,13 @@ import { Hero } from './shared/hero.model';
`]
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
heroes: Observable<Hero[]>;
selectedHero: Hero;
ngOnInit() {}
constructor(private heroService: HeroService) { }
ngOnInit() {
this.heroes = this.heroService.getHeroes();
}
}
// #enddocregion example

View File

@ -2,7 +2,7 @@
<div>
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes">
<li *ngFor="let hero of heroes | async" (click)="selectedHero=hero">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>

View File

@ -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<Hero[]>;
selectedHero: Hero;
ngOnInit() { }
constructor(private heroService: HeroService) { }
ngOnInit() {
this.heroes = this.heroService.getHeroes();
}
}
// #enddocregion example

View File

@ -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<Hero[]> {
return this.http.get('api/heroes')
.map(resp => resp.json().data as Hero[]);
}
}

View File

@ -1 +1,2 @@
export * from './hero.model';
export * from './hero.service';

View File

@ -1,3 +1,6 @@
<!-- #docregion -->
<toh-hero-button label="OK" (change)="doSomething()">
</toh-hero-button>
<!-- `heroHighlight` is both the directive name and the data-bound aliased property name -->
<h3 heroHighlight="skyblue">The Great Bombasto</h3>

View File

@ -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 ]
})

View File

@ -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: `<button>{{label}}</button>`
})
export class HeroButtonComponent {
// Pointless aliases
@Output('changeEvent') change = new EventEmitter<any>();
@Input('labelAttribute') label: string;
}

View File

@ -7,6 +7,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
template: `<button>{{label}}</button>`
})
export class HeroButtonComponent {
// No aliases
@Output() change = new EventEmitter<any>();
@Input() label: string;
}

View File

@ -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';
}
}

View File

@ -1 +1,2 @@
export * from './hero-button';
export * from './hero-highlight.directive';

View File

@ -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
<a href="https://wikipedia.org/wiki/Single_responsibility_principle" target="_blank"><i>Single Responsibility Principle</i> (SPR)</a>
to all components, services, and other symbols.
This helps make the app cleaner, easier to read and maintain, and more testable.
### <a id="01-01"></a>Rule of One
### <a id="01-01"></a>_Rule of One_
#### <a href="#01-01">Style 01-01</a>
.s-rule.do
:marked
@ -122,7 +124,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="01-02"></a>Small Functions
### <a id="01-02"></a>Small functions
#### <a href="#01-02">Style 01-02</a>
.s-rule.do
:marked
@ -189,7 +191,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-02"></a>Separate File Names with Dots and Dashes
### <a id="02-02"></a>Separate file names with dots and dashes
#### <a href="#02-02">Style 02-02</a>
.s-rule.do
@ -230,7 +232,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-03"></a>Symbols and File Names
### <a id="02-03"></a>Symbols and file names
#### <a href="#02-03">Style 02-03</a>
.s-rule.do
@ -336,7 +338,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-04"></a>Service Names
### <a id="02-04"></a>Service names
#### <a href="#02-04">Style 02-04</a>
.s-rule.do
@ -434,7 +436,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-06"></a>Directive Selectors
### <a id="02-06"></a>Directive selectors
#### <a href="#02-06">Style 02-06</a>
.s-rule.do
@ -453,7 +455,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-07"></a>Custom Prefix for Components
### <a id="02-07"></a>Custom prefix for components
#### <a href="#02-07">Style 02-07</a>
.s-rule.do
@ -495,7 +497,7 @@ a(href="#toc") Back to top
:marked
:marked
### <a id="02-08"></a>Custom Prefix for Directives
### <a id="02-08"></a>Custom prefix for directives
#### <a href="#02-08">Style 02-08</a>
.s-rule.do
@ -524,7 +526,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-09"></a>Pipe Names
### <a id="02-09"></a>Pipe names
#### <a href="#02-09">Style 02-09</a>
.s-rule.do
@ -564,7 +566,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-10"></a>Unit Test File Names
### <a id="02-10"></a>Unit test file names
#### <a href="#02-10">Style 02-10</a>
.s-rule.do
@ -628,7 +630,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-11"></a>End to End Test File Names
### <a id="02-11"></a>_End-to-End_ (E2E) test file names
#### <a href="#02-11">Style 02-11</a>
.s-rule.do
@ -667,7 +669,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="02-12"></a>Angular NgModule Names
### <a id="02-12"></a>Angular _NgModule_ names
#### <a href="#02-12">Style 02-12</a>
.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
### <a id="03-04"></a>Properties and Methods
### <a id="03-04"></a>Properties and methods
#### <a href="#03-04">Style 03-04</a>
.s-rule.do
@ -914,7 +916,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="03-06"></a>Import Line Spacing
### <a id="03-06"></a>Import line spacing
#### <a href="#03-06">Style 03-06</a>
.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
### <a id="04-01"></a>LIFT
### <a id="04-01"></a>_LIFT_
#### <a href="#04-01">Style 04-01</a>
.s-rule.do
@ -1068,7 +1070,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-05"></a>T-DRY (Try to be DRY)
### <a id="04-05"></a>_T-DRY_ (Try to be _DRY_)
#### <a href="#04-05">Style 04-05</a>
.s-rule.do
@ -1090,7 +1092,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-06"></a>Overall Structural Guidelines
### <a id="04-06"></a>Overall structural guidelines
#### <a href="#04-06">Style 04-06</a>
.s-rule.do
@ -1186,7 +1188,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-07"></a>Folders-by-Feature Structure
### <a id="04-07"></a>_Folders-by-feature_ structure
#### <a href="#04-07">Style 04-07</a>
.s-rule.do
@ -1230,7 +1232,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-08"></a>App Root Module
### <a id="04-08"></a>App _root module_
#### <a href="#04-08">Style 04-08</a>
.s-rule.do
@ -1256,7 +1258,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-09"></a>Feature Modules
### <a id="04-09"></a>Feature modules
#### <a href="#04-09">Style 04-09</a>
.s-rule.do
@ -1303,7 +1305,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-10"></a>Shared Feature Module
### <a id="04-10"></a>Shared feature module
#### <a href="#04-10">Style 04-10</a>
.s-rule.do
@ -1400,7 +1402,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-11"></a>Core Feature Module
### <a id="04-11"></a>Core feature module
#### <a href="#04-11">Style 04-11</a>
.s-rule.consider
@ -1531,7 +1533,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-12"></a>Prevent Reimport of Core Module
### <a id="04-12"></a>Prevent re-import of the core module
#### <a href="#04-12">Style 04-12</a>
Only the root `AppModule` should import the `CoreModule`.
@ -1563,7 +1565,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="04-13"></a>Lazy Loaded Folders
### <a id="04-13"></a>Lazy Loaded folders
#### <a href="#04-13">Style 04-13</a>
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
### <a id="04-14"></a>Never Directly Import Lazy Loaded Folders
### <a id="04-14"></a>Never directly import lazy loaded folders
#### <a href="#04-14">Style 04-14</a>
.s-rule.avoid
@ -1597,7 +1599,7 @@ a(href="#toc") Back to top
:marked
## Components
### <a id="05-02"></a>Component Selector Naming
### <a id="05-02"></a>Component selector names
#### <a href="#05-02">Style 05-02</a>
.s-rule.do
@ -1623,25 +1625,22 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="05-03"></a>Components as Elements
### <a id="05-03"></a>Components as elements
#### <a href="#05-03">Style 05-03</a>
.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
### <a id="05-04"></a>Extract Template and Styles to Their Own Files
### <a id="05-04"></a>Extract templates and styles to their own files
#### <a href="#05-04">Style 05-04</a>
.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
### <a id="05-12"></a>Decorate Input and Output Properties Inline
### <a id="05-12"></a>Decorate _input_ and _output_ properties
#### <a href="#05-12">Style 05-12</a>
.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
### <a id="05-13"></a>Avoid Renaming Inputs and Outputs
### <a id="05-13"></a>Avoid aliasing _inputs_ and _outputs_
#### <a href="#05-13">Style 05-13</a>
.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
### <a id="05-14"></a>Member Sequence
### <a id="05-14"></a>Member sequence
#### <a href="#05-14">Style 05-14</a>
.s-rule.do
@ -1796,7 +1822,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="05-15"></a>Put Logic in Services
### <a id="05-15"></a>Delegate complex component logic to services
#### <a href="#05-14">Style 05-15</a>
.s-rule.do
@ -1833,7 +1859,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="05-16"></a>Don't Prefix Output Properties
### <a id="05-16"></a>Don't prefix _output_ properties
#### <a href="#05-16">Style 05-16</a>
.s-rule.do
@ -1870,7 +1896,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="05-17"></a>Put Presentation Logic in the Component Class
### <a id="05-17"></a>Put presentation logic in the component class
#### <a href="#05-17">Style 05-17</a>
.s-rule.do
@ -1901,7 +1927,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="06-01"></a>Use Directives to Enhance an Existing Element
### <a id="06-01"></a>Use directives to enhance an element
#### <a href="#06-01">Style 06-01</a>
.s-rule.do
@ -1926,7 +1952,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="06-03"></a>Use HostListener and HostBinding Class Decorators
### <a id="06-03"></a>_HostListener_/_HostBinding_ decorators versus _host_ metadata
#### <a href="#06-03">Style 06-03</a>
.s-rule.consider
@ -1962,7 +1988,7 @@ a(href="#toc") Back to top
:marked
## Services
### <a id="07-01"></a>Services are Singletons within an Injector
### <a id="07-01"></a>Services are singletons
#### <a href="#07-01">Style 07-01</a>
.s-rule.do
@ -1984,7 +2010,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="07-02"></a>Single Responsibility
### <a id="07-02"></a>Single responsibility
#### <a href="#07-02">Style 07-02</a>
.s-rule.do
@ -2007,7 +2033,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="07-03"></a>Providing a Service
### <a id="07-03"></a>Providing a service
#### <a href="#07-03">Style 07-03</a>
.s-rule.do
@ -2043,7 +2069,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="07-04"></a>Use the @Injectable() Class Decorator
### <a id="07-04"></a>Use the @Injectable() class decorator
#### <a href="#07-04">Style 07-04</a>
.s-rule.do
@ -2071,7 +2097,7 @@ a(href="#toc") Back to top
:marked
## Data Services
### <a id="08-01"></a>Separate Data Calls
### <a id="08-01"></a>Talk to the server through a service
#### <a href="#08-01">Style 08-01</a>
.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
### <a id="09-01"></a>Implement Lifecycle Hooks Interfaces
### <a id="09-01"></a>Implement lifecycle hook interfaces
#### <a href="#09-01">Style 09-01</a>
.s-rule.do
@ -2157,7 +2183,7 @@ a(href="#toc") Back to top
.l-main-section
:marked
### <a id="A-02"></a>File Templates and Snippets
### <a id="A-02"></a>File templates and snippets
#### <a href="#A-02">Style A-02</a>
.s-rule.do