parent
cadd6c9823
commit
3f50248940
@ -1,5 +1,4 @@
|
||||
// #docregion
|
||||
/* recommended */
|
||||
|
||||
// app.component.ts
|
||||
import { Component } from '@angular/core';
|
||||
|
@ -1,5 +1,4 @@
|
||||
// #docregion
|
||||
/* recommended */
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { HEROES } from './mock-heroes';
|
||||
|
@ -1,93 +0,0 @@
|
||||
// #docplaster
|
||||
|
||||
// #docregion 01-01-1
|
||||
/* avoid */
|
||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<pre>{{heroes | json}}</pre>
|
||||
`,
|
||||
styleUrls: ['app/app.component.css']
|
||||
})
|
||||
export class AppComponent implements OnInit{
|
||||
title = 'Tour of Heroes';
|
||||
|
||||
heroes: Hero[] = [];
|
||||
|
||||
ngOnInit() {
|
||||
getHeroes().then(heroes => this.heroes = heroes);
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap(AppComponent, []);
|
||||
|
||||
function getHeroes() {
|
||||
return // some promise of data;
|
||||
}
|
||||
// #enddocregion 01-01-1
|
||||
|
||||
|
||||
// #docregion 01-01-2
|
||||
/* recommended */
|
||||
|
||||
// main.ts
|
||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
bootstrap(AppComponent, []);
|
||||
/* recommended */
|
||||
|
||||
// app.component.ts
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `
|
||||
<pre>{{heroes | json}}</pre>
|
||||
`,
|
||||
styleUrls: ['app/app.component.css'],
|
||||
providers: [HeroService]
|
||||
})
|
||||
export class AppComponent implements OnInit{
|
||||
heroes: Hero[] = [];
|
||||
|
||||
constructor(private heroService: HeroService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.heroService.getHeroes()
|
||||
.then(heroes => this.heroes = heroes);
|
||||
}
|
||||
}
|
||||
// #enddocregion 01-01-2
|
||||
|
||||
// #docregion 01-01-3
|
||||
/* recommended */
|
||||
|
||||
// hero.service.ts
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
|
||||
@Injectable()
|
||||
export class HeroService {
|
||||
getHeroes() {
|
||||
return Promise.resolve(HEROES);
|
||||
}
|
||||
}
|
||||
// #enddocregion 01-01-3
|
||||
|
||||
// #docregion 01-01-4
|
||||
/* recommended */
|
||||
|
||||
// hero.ts
|
||||
export class Hero {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
// #enddocregion 01-01-4
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Directive } from 'angular2/core';
|
||||
import { Directive } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
// #docregion example
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
// #docregion example
|
||||
|
@ -2,7 +2,7 @@
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { IHero } from './hero.model.avoid';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
// #docregion example
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Hero } from './hero.model';
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ToastService {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
// #docregion example
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ToastService {
|
||||
|
@ -2,8 +2,8 @@
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {Http, Response} from 'angular2/http';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Http, Response} from '@angular/http';
|
||||
|
||||
import {Hero} from './hero.model';
|
||||
import {ExceptionService, SpinnerService, ToastService} from '../../shared';
|
||||
|
@ -1,7 +1,7 @@
|
||||
// #docregion
|
||||
// #docregion example
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Http, Response } from 'angular2/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Http, Response } from '@angular/http';
|
||||
|
||||
import { Hero } from './hero.model';
|
||||
import { ExceptionService, SpinnerService, ToastService } from '../../shared';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ExceptionService { }
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, OnDestroy, OnInit} from 'angular2/core';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
import { SpinnerService } from './spinner.service';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
export interface ISpinnerState { }
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ToastService } from './toast.service';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ToastService {
|
||||
|
@ -2,9 +2,9 @@
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
import { ExceptionService, SpinnerService, ToastService } from '../../../app/shared';
|
||||
import { Http, Response } from 'angular2/http';
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { ExceptionService, SpinnerService, ToastService } from '../../shared';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Hero } from './hero.model';
|
||||
// #enddocregion example
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
// #docregion
|
||||
// #docregion example
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Http, Response } from 'angular2/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Http, Response } from '@angular/http';
|
||||
|
||||
import { Hero } from './hero.model';
|
||||
import { ExceptionService, SpinnerService, ToastService } from '../../../app/shared';
|
||||
import { ExceptionService, SpinnerService, ToastService } from '../../shared';
|
||||
// #enddocregion example
|
||||
|
||||
@Injectable()
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ExceptionService { }
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, OnDestroy, OnInit} from 'angular2/core';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
import { SpinnerService } from './spinner.service';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
export interface ISpinnerState { }
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ToastService } from './toast.service';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ToastService {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { CONFIG } from '../shared/config';
|
||||
import { EntityService } from '../shared/entity.service';
|
||||
|
@ -1,7 +1,7 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion example
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import {
|
||||
CONFIG,
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
import { HeroesComponent } from './+heroes/index';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Injectable} from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class EntityService { }
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ExceptionService { }
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, EventEmitter, Output } from 'angular2/core';
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class FilterService {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Pipe, PipeTransform } from 'angular2/core';
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'initCaps' })
|
||||
export class InitCapsPipe implements PipeTransform {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ModalService } from './modal.service';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ModalService {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ModalService } from '../';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, OnDestroy, OnInit} from 'angular2/core';
|
||||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||
|
||||
import { SpinnerService } from './spinner.service';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
export interface ISpinnerState { }
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ToastService } from './toast.service';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class ToastService {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
import { HeroesComponent } from './+heroes';
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { Hero } from './shared/hero.model';
|
||||
// #docregion example
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class Logger {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
import { HeroesComponent } from './+heroes';
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
import { HeroesComponent } from './+heroes';
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
<!-- #docregion -->
|
||||
<!-- avoid -->
|
||||
|
||||
<div tohHeroButton></div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
// #docregion
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { Hero } from './shared/hero.model';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component, EventEmitter } from 'angular2/core';
|
||||
import { Component, EventEmitter } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
@Component({
|
||||
|
@ -1,4 +1,5 @@
|
||||
<!-- #docregion -->
|
||||
<!-- avoid -->
|
||||
|
||||
<toh-hero-button labelAttribute="OK" (changeEvent)="doSomething()">
|
||||
</toh-hero-button>
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component, Input, Output, EventEmitter } from 'angular2/core';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
@Component({
|
||||
|
@ -1,7 +1,8 @@
|
||||
// #docregion
|
||||
import { OnInit } from 'angular2/core';
|
||||
import { OnInit } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
export class ToastComponent implements OnInit {
|
||||
|
||||
private defaults = {
|
||||
|
@ -42,4 +42,4 @@ export class ToastComponent implements OnInit {
|
||||
window.setTimeout(() => this.hide(), 2500);
|
||||
}
|
||||
}
|
||||
// #endregion example
|
||||
// #enddocregion example
|
||||
|
@ -1,8 +1,8 @@
|
||||
// #docregion
|
||||
/* avoid */
|
||||
|
||||
import { OnInit } from 'angular2/core';
|
||||
import { Http, Response } from 'angular2/http';
|
||||
import { OnInit } from '@angular/core';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { Hero } from '../shared/hero.model';
|
||||
@ -18,7 +18,7 @@ export class HeroListComponent implements OnInit {
|
||||
.map((response: Response) => <Hero[]>response.json().data)
|
||||
.catch(this.catchBadResponse)
|
||||
.finally(() => this.hideSpinner())
|
||||
.subscribe(heroes => this.heroes = heroes);
|
||||
.subscribe((heroes: Hero[]) => this.heroes = heroes);
|
||||
}
|
||||
ngOnInit() {
|
||||
this.getHeroes();
|
||||
|
@ -1,3 +1,4 @@
|
||||
<!-- #docregion -->
|
||||
<!-- avoid -->
|
||||
|
||||
<toh-hero (onSavedTheDay)="onSavedTheDay($event)"></toh-hero>
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component, Output, EventEmitter } from 'angular2/core';
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component, Output, EventEmitter } from '@angular/core';
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'toh-hero',
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { Hero } from '../shared/hero.model';
|
||||
// #docregion example
|
||||
|
@ -0,0 +1,2 @@
|
||||
<!-- #docregion -->
|
||||
<div [tohHightlight]>Bombasta</div>
|
@ -0,0 +1,13 @@
|
||||
// #docregion
|
||||
import { Directive, HostListener } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
@Directive({
|
||||
selector: '[tohHighlight]'
|
||||
})
|
||||
export class HighlightDirective {
|
||||
@HostListener('mouseover') onMouseEnter() {
|
||||
// do highlight work
|
||||
}
|
||||
}
|
||||
// #enddocregion example
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Directive, HostBinding, HostListener } from 'angular2/core';
|
||||
import { Directive, HostBinding, HostListener } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
@ -17,5 +17,4 @@ export class ValidatorDirective {
|
||||
// do work
|
||||
}
|
||||
}
|
||||
export class ValidateDirective { }
|
||||
// #enddocregion example
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Directive, HostBinding, HostListener } from 'angular2/core';
|
||||
import { Directive, HostBinding, HostListener } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
@Directive({
|
||||
@ -11,5 +11,4 @@ export class ValidatorDirective {
|
||||
// do work
|
||||
}
|
||||
}
|
||||
export class ValidateDirective { }
|
||||
// #enddocregion example
|
||||
|
@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
import { Inject } from 'angular2/core';
|
||||
import { Http } from 'angular2/http';
|
||||
import { Inject } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
|
||||
import { HeroService } from './hero.service';
|
||||
// #docregion example
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from 'angular2/core';
|
||||
import { Component } from '@angular/core';
|
||||
// #docregion example
|
||||
/* avoid */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
// #docregion example
|
||||
@Component({
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'toh-dashboard',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'toh-heroes',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from 'angular2/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class HeroService {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from 'angular2/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'toh-nav',
|
||||
|
@ -56,7 +56,13 @@
|
||||
"nextable": true,
|
||||
"basics": true
|
||||
},
|
||||
|
||||
|
||||
"style-guide": {
|
||||
"title": "Style Guide",
|
||||
"intro": "Write Angular 2 with style.",
|
||||
"basics": true
|
||||
},
|
||||
|
||||
"attribute-directives": {
|
||||
"title": "Attribute Directives",
|
||||
"intro": "Attribute directives attach behavior to elements."
|
||||
@ -66,7 +72,7 @@
|
||||
"title": "Component Styles",
|
||||
"intro": "Learn how to apply CSS styles to components."
|
||||
},
|
||||
|
||||
|
||||
"hierarchical-dependency-injection": {
|
||||
"title": "Hierarchical Dependency Injectors",
|
||||
"navTitle": "Hierarchical Injectors",
|
||||
@ -103,13 +109,7 @@
|
||||
"title": "Structural Directives",
|
||||
"intro": "Angular has a powerful template engine that lets us easily manipulate the DOM structure of our elements."
|
||||
},
|
||||
|
||||
"style-guide": {
|
||||
"title": "Style Guide",
|
||||
"intro": "Write Angular 2 with style.",
|
||||
"hide": true
|
||||
},
|
||||
|
||||
|
||||
"testing": {
|
||||
"title": "Testing",
|
||||
"intro": "Techniques and practices for testing an Angular 2 app",
|
||||
@ -121,7 +121,7 @@
|
||||
"intro": "TypeScript configuration for Angular 2 developers",
|
||||
"hide": true
|
||||
},
|
||||
|
||||
|
||||
"upgrade": {
|
||||
"title": "Upgrading from 1.x",
|
||||
"intro": "Angular 1 applications can be incrementally upgraded to Angular 2.",
|
||||
|
@ -56,7 +56,13 @@
|
||||
"nextable": true,
|
||||
"basics": true
|
||||
},
|
||||
|
||||
|
||||
"style-guide": {
|
||||
"title": "Style Guide",
|
||||
"intro": "Write Angular 2 with style.",
|
||||
"basics": true
|
||||
},
|
||||
|
||||
"attribute-directives": {
|
||||
"title": "Attribute Directives",
|
||||
"intro": "Attribute directives attach behavior to elements."
|
||||
@ -66,7 +72,7 @@
|
||||
"title": "Component Styles",
|
||||
"intro": "Learn how to apply CSS styles to components."
|
||||
},
|
||||
|
||||
|
||||
"hierarchical-dependency-injection": {
|
||||
"title": "Hierarchical Dependency Injectors",
|
||||
"navTitle": "Hierarchical Injectors",
|
||||
@ -102,13 +108,7 @@
|
||||
"title": "Structural Directives",
|
||||
"intro": "Angular has a powerful template engine that lets us easily manipulate the DOM structure of our elements."
|
||||
},
|
||||
|
||||
"style-guide": {
|
||||
"title": "Style Guide",
|
||||
"intro": "Write Angular 2 with style.",
|
||||
"hide": true
|
||||
},
|
||||
|
||||
|
||||
"testing": {
|
||||
"title": "Testing",
|
||||
"intro": "Techniques and practices for testing an Angular 2 app",
|
||||
@ -120,7 +120,7 @@
|
||||
"intro": "TypeScript configuration for Angular 2 developers",
|
||||
"hide": true
|
||||
},
|
||||
|
||||
|
||||
"upgrade": {
|
||||
"title": "Upgrading from 1.x",
|
||||
"intro": "Angular 1 applications can be incrementally upgraded to Angular 2."
|
||||
|
@ -57,6 +57,12 @@
|
||||
"basics": true
|
||||
},
|
||||
|
||||
"style-guide": {
|
||||
"title": "Style Guide",
|
||||
"intro": "Write Angular 2 with style.",
|
||||
"basics": true
|
||||
},
|
||||
|
||||
"attribute-directives": {
|
||||
"title": "Attribute Directives",
|
||||
"intro": "Attribute directives attach behavior to elements."
|
||||
@ -103,12 +109,6 @@
|
||||
"intro": "Angular has a powerful template engine that lets us easily manipulate the DOM structure of our elements."
|
||||
},
|
||||
|
||||
"style-guide": {
|
||||
"title": "Style Guide",
|
||||
"intro": "Write Angular 2 with style.",
|
||||
"hide": true
|
||||
},
|
||||
|
||||
"testing": {
|
||||
"title": "Testing",
|
||||
"intro": "Techniques and practices for testing an Angular 2 app"
|
||||
|
@ -1,7 +1,7 @@
|
||||
include ../_util-fns
|
||||
|
||||
:marked
|
||||
Welcome to the Angular 2 Guide of Style (version 6)
|
||||
Welcome to the Angular 2 Style Guide
|
||||
|
||||
## Purpose
|
||||
|
||||
@ -14,33 +14,33 @@ include ../_util-fns
|
||||
## Style Vocabulary
|
||||
|
||||
Each guideline describes either a good or bad practice, and all have a consistent presentation.
|
||||
|
||||
|
||||
The wording of each guideline indicates how strong the recommendation is.
|
||||
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** is one that should always be followed.
|
||||
_Always_ might be a bit too strong a word.
|
||||
Guidelines that literally should always be followed are extremely rare.
|
||||
**Do** is one that should always be followed.
|
||||
_Always_ might be a bit too strong of a word.
|
||||
Guidelines that literally should always be followed are extremely rare.
|
||||
On the other hand, we need a really unusual case for breaking a *Do* guideline.
|
||||
|
||||
|
||||
.s-rule.consider
|
||||
:marked
|
||||
**Consider** guidelines should generally be followed.
|
||||
**Consider** guidelines should generally be followed.
|
||||
If you fully understand the meaning behind the guideline and have a good reason to deviate, then do so. Please strive to be consistent.
|
||||
|
||||
|
||||
.s-rule.avoid
|
||||
:marked
|
||||
**Avoid** indicates something we should almost never do. Code examples to *avoid* have an unmistakeable red header.
|
||||
.l-main-section
|
||||
|
||||
|
||||
:marked
|
||||
## File Structure Conventions
|
||||
|
||||
Some code examples display a file that has one or more similarly named companion files. (e.g. hero.component.ts and hero.component.html).
|
||||
|
||||
The guideline will use the shortcut `hero.component.ts|html|css|spec` to represent that various files. This makes this guide's file structures easier to read and more terse.
|
||||
|
||||
Some code examples display a file that has one or more similarly named companion files. (e.g. hero.component.ts and hero.component.html).
|
||||
|
||||
The guideline will use the shortcut `hero.component.ts|html|css|spec` to represent those various files. Using this shortcut makes this guide's file structures easier to read and more terse.
|
||||
|
||||
.l-main-section
|
||||
a(id='toc')
|
||||
|
||||
@ -63,7 +63,7 @@ a(id='toc')
|
||||
:marked
|
||||
## Single Responsibility
|
||||
|
||||
We apply the [Single Responsibility Principle](https:\/\/en.wikipedia.org/wiki/Single_responsibility_principle) to all Components, Services, and other symbols we create. This helps make our app cleaner, easier to read and maintain, and more testable.
|
||||
We apply the [Single Responsibility Principle](https:\/\/en.wikipedia.org/wiki/Single_responsibility_principle) to all Components, Services, and other symbols we create. This helps make our app cleaner, easier to read and maintain, and more testable.
|
||||
|
||||
### Rule of One
|
||||
<a id="01-01"></a>
|
||||
@ -89,7 +89,7 @@ a(id='toc')
|
||||
**Why?** A single component can be the default export for its file which facilitates lazy loading with the Component Router.
|
||||
:marked
|
||||
The key is to make the code more reusable, easier to read, and less mistake prone.
|
||||
|
||||
|
||||
The following *negative* example defines the `AppComponent`, bootstraps the app, defines the `Hero` model object, and loads heroes from the server ... all in the same file. *Don't do this*.
|
||||
|
||||
+makeExample('style-guide/ts/01-01/app/heroes/hero.component.avoid.ts', '', 'app/heroes/hero.component.ts')(avoid=1)
|
||||
@ -101,13 +101,13 @@ a(id='toc')
|
||||
style-guide/ts/01-01/app/app.component.ts,
|
||||
style-guide/ts/01-01/app/heroes/heroes.component.ts,
|
||||
style-guide/ts/01-01/app/heroes/shared/hero.service.ts,
|
||||
style-guide/ts/01-01/app/heroes/shared/hero.model.ts,
|
||||
style-guide/ts/01-01/app/heroes/shared/hero.model.ts,
|
||||
style-guide/ts/01-01/app/heroes/shared/mock-heroes.ts`,
|
||||
'',
|
||||
`app/main.ts,
|
||||
app/app.component.ts,
|
||||
app/heroes/heroes.component.ts,
|
||||
app/heroes/shared/hero.service.ts,
|
||||
`app/main.ts,
|
||||
app/app.component.ts,
|
||||
app/heroes/heroes.component.ts,
|
||||
app/heroes/shared/hero.service.ts,
|
||||
app/heroes/shared/hero.model.ts,
|
||||
app/heroes/shared/mock-heroes.ts`)
|
||||
|
||||
@ -124,7 +124,7 @@ a(href="#toc") Back to top
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** define small functions
|
||||
|
||||
|
||||
.s-rule.consider
|
||||
:marked
|
||||
**Consider** limiting to no more than 75 lines.
|
||||
@ -155,7 +155,7 @@ a(href="#toc") Back to top
|
||||
:marked
|
||||
## Naming
|
||||
|
||||
Naming conventions are hugely important to maintainbility and readability. This guide will recommend naming conventions for the file name and the symbol name.
|
||||
Naming conventions are hugely important to maintainability and readability. This guide recommends naming conventions for the file name and the symbol name.
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
@ -166,7 +166,7 @@ a(href="#toc") Back to top
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use consistent names for all symbols.
|
||||
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** follow a pattern that describes the symbol's feature then its type. The recommended pattern is `feature.type.ts`.
|
||||
@ -177,7 +177,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** The naming conventions should simply help we find our code faster and make it easier to understand.
|
||||
**Why?** The naming conventions should simply help us find our code faster and make it easier to understand.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
@ -193,7 +193,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use dashes to separate words.
|
||||
**Do** use dashes to separate words.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
@ -245,7 +245,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Upper camel case is conventional for identifying object that can be instantiated using a constructor.
|
||||
**Why?** Upper camel case is conventional for identifying objects that can be instantiated using a constructor.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
@ -254,7 +254,7 @@ a(href="#toc") Back to top
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Symbol Name
|
||||
th File Name
|
||||
@ -310,12 +310,12 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use consistent names for all services named after their feature.
|
||||
|
||||
**Do** use consistent names for all services named after their feature.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use upper camel case for services.
|
||||
|
||||
**Do** use upper camel case for services.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** suffix services with `Service` when it is not clear what they are (e.g. when they are nouns).
|
||||
@ -335,7 +335,7 @@ a(href="#toc") Back to top
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Symbol Name
|
||||
th File Name
|
||||
@ -387,13 +387,13 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** Follows a familar convention from other technology platforms.
|
||||
**Why?** Follows a familiar convention from other technology platforms.
|
||||
|
||||
a(href="#toc") Back to top
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Use lower camel case for Directive Selectors
|
||||
### Directive Selectors
|
||||
<a id="02-06"></a>
|
||||
#### Style 02-06
|
||||
|
||||
@ -420,18 +420,18 @@ a(href="#toc") Back to top
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use a custom prefix for the selector of our components. For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the prefix `admin` represents an admin feature area.
|
||||
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use a prefix that identifies the feature area or the app itself.
|
||||
|
||||
**Do** use a prefix that identifies the feature area or the app itself.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Prevents name collisions.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Makes it easier to promote and share our feature in other apps.
|
||||
**Why?** Makes it easier to promote and share our feature in other apps.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
@ -456,7 +456,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use a custom prefix for the selector of our directives (for instance below is used the prefix `toh` from **T**our **o**f **H**eroes).
|
||||
**Do** use a custom prefix for the selector of our directives (for instance below we use the prefix `toh` from **T**our **o**f **H**eroes).
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
@ -491,7 +491,7 @@ a(href="#toc") Back to top
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Symbol Name
|
||||
th File Name
|
||||
@ -524,7 +524,7 @@ a(href="#toc") Back to top
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** name test specification files the same as the component they test.
|
||||
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** name test specification files with a suffix of `.spec`.
|
||||
@ -541,7 +541,7 @@ a(href="#toc") Back to top
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Symbol Name
|
||||
th File Name
|
||||
@ -603,7 +603,7 @@ a(href="#toc") Back to top
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Symbol Name
|
||||
th File Name
|
||||
@ -634,8 +634,8 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use upper camel case when naming classes.
|
||||
|
||||
**Do** use upper camel case when naming classes.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Follows conventional thinking for class names.
|
||||
@ -660,8 +660,8 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use uppercase with underscores when naming constants.
|
||||
|
||||
**Do** use uppercase with underscores when naming constants.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Follows conventional thinking for constants.
|
||||
@ -686,15 +686,15 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** name an interface using upper camel case.
|
||||
**Do** name an interface using upper camel case.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Consider** naming an interface without an `I` prefix.
|
||||
**Consider** naming an interface without an `I` prefix.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** When we use types, we can often simply use the class as the type.
|
||||
**Why?** When we use types, we can often simply use the class as the type.
|
||||
|
||||
+makeExample('style-guide/ts/03-03/app/shared/hero-collector.service.avoid.ts', 'example', 'app/shared/hero-collector.service.ts')(avoid=1)
|
||||
:marked
|
||||
@ -712,23 +712,23 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use lower camel case to name properties and methods.
|
||||
|
||||
**Do** use lower camel case to name properties and methods.
|
||||
|
||||
.s-rule.avoid
|
||||
:marked
|
||||
**Avoid** prefixing private properties and methods with an underscore.
|
||||
|
||||
**Avoid** prefixing private properties and methods with an underscore.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Follows conventional thinking for properties and methods.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** JavaScript lacks a true private property or method.
|
||||
**Why?** JavaScript lacks a true private property or method.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** TypeScript tooling makes it easy to identify private vs public properties and methods.
|
||||
**Why?** TypeScript tooling makes it easy to identify private vs public properties and methods.
|
||||
|
||||
+makeExample('style-guide/ts/03-04/app/shared/toast/toast.service.avoid.ts', 'example', 'app/shared/toast/toast.service.ts')(avoid=1)
|
||||
:marked
|
||||
@ -746,11 +746,11 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** leave one whitespace character inside of the `import` statements' curly braces when destructuring.
|
||||
|
||||
**Do** leave one whitespace character inside of the `import` statements' curly braces when destructuring.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** Whitespace makes it easier to read the imports.
|
||||
**Why?** Whitespace makes it easier to read the imports.
|
||||
|
||||
+makeExample('style-guide/ts/03-05/app/+heroes/shared/hero.service.avoid.ts', 'example', 'app/+heroes/shared/hero.service.ts')(avoid=1)
|
||||
:marked
|
||||
@ -768,19 +768,19 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** leave one empty line between third party imports and imports of code we created.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** list import lines alphabetized by the module.
|
||||
**Do** leave one empty line between third party imports and imports of code we created.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** list destructured imported assets alphabetized.
|
||||
**Do** list import lines alphabetized by the module.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** list destructured imported assets alphabetically.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** The empty line makes it easy to read and locate imports.
|
||||
**Why?** The empty line makes it easy to read and locate imports.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
@ -798,9 +798,9 @@ a(href="#toc") Back to top
|
||||
:marked
|
||||
## Application Structure
|
||||
|
||||
Have a near term view of implementation and a long term vision. Start small but keep in mind on where the app is heading down the road.
|
||||
|
||||
All of the app's code goes in a root folder named `app`. All content is 1 feature per file. Each component, service, pipe is in its own file. All 3rd party vendor scripts are stored in another root folder and not in the `app` folder. We didn't write them and we don't want them cluttering our app. Use the naming conventions for file in this guide.
|
||||
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.
|
||||
|
||||
All of the app's code goes in a folder named `app`. All content is 1 feature per file. Each component, service, and pipe is in its own file. All 3rd party vendor scripts are stored in another folder and not in the `app` folder. We didn't write them and we don't want them cluttering our app. Use the naming conventions for files in this guide.
|
||||
|
||||
a(href="#toc") Back to top
|
||||
|
||||
@ -812,8 +812,8 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** structure the app such that we can `L`ocate our code quickly, `I`dentify the code at a glance, keep the `F`lattest structure we can, and `T`ry to stay DRY.
|
||||
|
||||
**Do** structure the app such that we can `L`ocate our code quickly, `I`dentify the code at a glance, keep the `F`lattest structure we can, and `T`ry to be DRY.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** define the structure to follow these four basic guidelines, listed in order of importance.
|
||||
@ -853,11 +853,11 @@ a(href="#toc") Back to top
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** be descriptive with file names and keeping the contents of the file to exactly one component.
|
||||
|
||||
|
||||
.s-rule.avoid
|
||||
:marked
|
||||
**Avoid** files with multiple components, multiple services, or a mixture.
|
||||
|
||||
**Avoid** files with multiple components, multiple services, or a mixture.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** We spend less time hunting and pecking for code, and become more efficient. If this means we want longer file names, then so be it.
|
||||
@ -876,28 +876,28 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** keep a flat folder structure as long as possible.
|
||||
|
||||
**Do** keep a flat folder structure as long as possible.
|
||||
|
||||
.s-rule.consider
|
||||
:marked
|
||||
**Consider** creating fodlers when we get to seven or more files.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** Nobody wants to search 7 levels of folders to find a file. In a folder structure there is no hard and fast number rule, but when a folder has 7-10 files, that may be time to create subfolders. We base it on our comfort level. Use a flatter structure until there is an obvious value (to help the rest of LIFT) in creating a new folder.
|
||||
**Why?** Nobody wants to search seven levels of folders to find a file. In a folder structure there is no hard and fast number rule, but when a folder has seven to ten files, that may be time to create subfolders. We base it on our comfort level. Use a flatter structure until there is an obvious value (to help the rest of LIFT) in creating a new folder.
|
||||
|
||||
a(href="#toc") Back to top
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
### T-DRY (Try to Stick to DRY)
|
||||
### T-DRY (Try to be DRY)
|
||||
<a id="04-05"></a>
|
||||
#### Style 04-05
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** be DRY
|
||||
|
||||
**Do** be DRY (Don't Repeat Yourself)
|
||||
|
||||
.s-rule.avoid
|
||||
:marked
|
||||
**Avoid** being so DRY that we sacrifice readability.
|
||||
@ -916,23 +916,23 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** start small but keep in mind where the app is heading down the road.
|
||||
**Do** start small but keep in mind where the app is heading down the road.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** have a near term view of implementation and a long term vision.
|
||||
**Do** have a near term view of implementation and a long term vision.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** put all of the app's code in a root folder named `app`.
|
||||
**Do** put all of the app's code in a folder named `app`.
|
||||
|
||||
.s-rule.consider
|
||||
:marked
|
||||
**Consider** creating a folder for each component including its `.ts`, `.html`, `.css` and `.spec` file.
|
||||
**Consider** creating a folder for each component including its `.ts`, `.html`, `.css` and `.spec` file.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Helps keep the app small and easy to maintain in the early stages, while being easy to evolve as the app grows.
|
||||
**Why?** Helps us keep the app structure small and easy to maintain in the early stages, while being easy to evolve as the app grows.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
@ -962,7 +962,7 @@ a(href="#toc") Back to top
|
||||
.file heroes.component.ts|html|css|spec.ts
|
||||
.file index.ts
|
||||
.file shared
|
||||
.children
|
||||
.children
|
||||
.file ...
|
||||
.file app.component.ts|html|css|spec.ts
|
||||
.file main.ts
|
||||
@ -984,11 +984,11 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** put all shared files within a component feature in a `shared` folder.
|
||||
**Do** put all shared files within a component feature in a `shared` folder.
|
||||
|
||||
.s-rule.consider
|
||||
:marked
|
||||
**Consider** creating a folder for each component including its `.ts`, `.html`, `.css` and `.spec` file.
|
||||
**Consider** creating a folder for each component including its `.ts`, `.html`, `.css` and `.spec` file.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
@ -1023,11 +1023,11 @@ a(href="#toc") Back to top
|
||||
.file heroes.component.ts|html|css|spec.ts
|
||||
.file index.ts
|
||||
.file shared
|
||||
.children
|
||||
.children
|
||||
.file exception.service.ts|spec.ts
|
||||
.file index.ts
|
||||
.file nav
|
||||
.children
|
||||
.children
|
||||
.file ...
|
||||
.file app.component.ts|html|css|spec.ts
|
||||
.file main.ts
|
||||
@ -1045,8 +1045,8 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** create folders named for the feature they represent.
|
||||
|
||||
**Do** create folders named for the feature they represent.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** A developer can locate the code, identify what each file represents at a glance, the structure is as flat as it can be, and there is no repetitive nor redundant names.
|
||||
@ -1064,7 +1064,7 @@ a(href="#toc") Back to top
|
||||
**Why?** When there are a lot of files (e.g. 10+) locating them is easier with a consistent folder structures and more difficult in flat structures.
|
||||
|
||||
:marked
|
||||
Below is an example of a small app with folders per component.
|
||||
Below is an example of a small app with folders per component.
|
||||
|
||||
.example-title Folders per Component
|
||||
.filetree
|
||||
@ -1099,7 +1099,7 @@ a(href="#toc") Back to top
|
||||
.file villains.component.ts|html|css|spec.ts
|
||||
.file index.ts
|
||||
.file shared
|
||||
.children
|
||||
.children
|
||||
.file nav
|
||||
.children
|
||||
.file ...
|
||||
@ -1124,11 +1124,11 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** put shared layout components in their own folder, under the `shared` folder.
|
||||
**Do** put shared layout components in their own folder, under the `shared` folder.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** We need a place to host our layout for our app. Our navigation bar, footer, and other aspects of the app that are needed for the entire app.
|
||||
**Why?** We need a place to host our layout for our app. Our navigation bar, footer, and other aspects of the app that are needed for the entire app.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
@ -1144,7 +1144,7 @@ a(href="#toc") Back to top
|
||||
.children
|
||||
.file ...
|
||||
.file shared
|
||||
.children
|
||||
.children
|
||||
.file nav
|
||||
.children
|
||||
.file index.ts
|
||||
@ -1176,7 +1176,7 @@ a(href="#toc") Back to top
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** name this barrel file `index.ts`.
|
||||
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** A barrel aggregates many imports into a single import.
|
||||
@ -1254,7 +1254,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** put the contents of lazy loaded features in a *lazy loaded folder*.
|
||||
**Do** put the contents of lazy loaded features in a *lazy loaded folder*.
|
||||
A typical *lazy loaded folder* contains a *routing component*, its child components, and their related assets and modules.
|
||||
|
||||
.s-why.s-why-last
|
||||
@ -1296,7 +1296,7 @@ a(href="#toc") Back to top
|
||||
.file dashboard.component.ts|html|css|spec.ts
|
||||
.file index.ts
|
||||
:marked
|
||||
|
||||
|
||||
a(href="#toc") Back to top
|
||||
|
||||
.l-main-section
|
||||
@ -1376,7 +1376,7 @@ a(href="#toc") Back to top
|
||||
`style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.ts,
|
||||
style-guide/ts/05-02/app/app.component.html`,
|
||||
'example,',
|
||||
`app/heroes/shared/hero-button/hero-button.component.ts,
|
||||
`app/heroes/shared/hero-button/hero-button.component.ts,
|
||||
app/app.component.html`)
|
||||
:marked
|
||||
|
||||
@ -1414,7 +1414,7 @@ a(href="#toc") Back to top
|
||||
`style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.ts,
|
||||
style-guide/ts/05-03/app/app.component.html`,
|
||||
'example,',
|
||||
`app/heroes/shared/hero-button/hero-button.component.ts,
|
||||
`app/heroes/shared/hero-button/hero-button.component.ts,
|
||||
app/app.component.html`)
|
||||
:marked
|
||||
|
||||
@ -1454,8 +1454,8 @@ a(href="#toc") Back to top
|
||||
style-guide/ts/05-04/app/heroes/heroes.component.html,
|
||||
style-guide/ts/05-04/app/heroes/heroes.component.css`,
|
||||
'example,,',
|
||||
`app/heroes/heroes.component.ts,
|
||||
app/heroes/heroes.component.html,
|
||||
`app/heroes/heroes.component.ts,
|
||||
app/heroes/heroes.component.html,
|
||||
app/heroes/heroes.component.css`)
|
||||
:marked
|
||||
|
||||
@ -1481,7 +1481,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** If we ever need to rename the name of the property, or event name associated to [`@Input`](https://angular.io/docs/ts/latest/api/core/Input-var.html) or respectively [`@Output`](https://angular.io/docs/ts/latest/api/core/Output-var.html) we can modify it on a single place.
|
||||
**Why?** If we ever need to rename the property or event name associated to [`@Input`](https://angular.io/docs/ts/latest/api/core/Input-var.html) or [`@Output`](https://angular.io/docs/ts/latest/api/core/Output-var.html) we can modify it on a single place.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
@ -1523,7 +1523,7 @@ a(href="#toc") Back to top
|
||||
`style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.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-button.component.ts,
|
||||
app/app.component.html`)
|
||||
:marked
|
||||
|
||||
@ -1557,13 +1557,13 @@ a(href="#toc") Back to top
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Defer Logic to Services
|
||||
### Put Logic in Services
|
||||
<a id="05-15"></a>
|
||||
#### Style 05-15
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** defer logic in a component by delegating to services.
|
||||
**Do** limit logic in a component to only that required for the view. All other logic should be delegated to services.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
@ -1625,7 +1625,7 @@ a(href="#toc") Back to top
|
||||
`style-guide/ts/05-16/app/heroes/hero.component.ts,
|
||||
style-guide/ts/05-16/app/app.component.html`,
|
||||
'example,',
|
||||
`app/heroes/hero.component.ts,
|
||||
`app/heroes/hero.component.ts,
|
||||
app/app.component.html`)
|
||||
:marked
|
||||
|
||||
@ -1647,7 +1647,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** Keeping the logic of the components in their controller, instead of template will improve testability, maintability, reusability.
|
||||
**Why?** Keeping the component's presentation logic in the class instead of the template improves testability, maintainability, and reusability.
|
||||
|
||||
+makeExample('style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.avoid.ts', 'example', 'app/heroes/hero-list/hero-list.component.ts')(avoid=1)
|
||||
:marked
|
||||
@ -1663,6 +1663,32 @@ a(href="#toc") Back to top
|
||||
|
||||
a(href="#toc") Back to top
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Use Directives to Enhance an Existing Element
|
||||
<a id="06-01"></a>
|
||||
#### Style 06-01
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use attribute directives when you have presentation logic without a template.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Attributes directives don't have an associated template.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** An element may have more than one attribute directive applied.
|
||||
|
||||
+makeExample('style-guide/ts/06-01/app/shared/highlight.directive.ts', 'example', 'app/shared/highlight.directive.ts')
|
||||
:marked
|
||||
|
||||
+makeExample('style-guide/ts/06-01/app/app.component.html', null, 'app/app.component.html')
|
||||
:marked
|
||||
|
||||
a(href="#toc") Back to top
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Use HostListener and HostBinding Class Decorators
|
||||
@ -1675,7 +1701,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** The name of the property, or method name associated to @HostBinding or respectively @HostListener should be modified only in a single place - in the directive's controller. In contrast if we use host we need to modify both the property declaration inside the controller, and the metadata associated to the directive.
|
||||
**Why?** The property or method name associated with @HostBinding or respectively @HostListener should be modified only in a single place - in the directive's class. In contrast if we use host we need to modify both the property declaration inside the controller, and the metadata associated to the directive.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
@ -1700,7 +1726,7 @@ a(href="#toc") Back to top
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use services as singletons within the same injector. Use them for sharing data and functionality.
|
||||
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** Services are ideal for sharing methods across a feature area or an app.
|
||||
@ -1722,12 +1748,12 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** create services with a single responsibility that is encapsulated by its context.
|
||||
|
||||
**Do** create services with a single responsibility that is encapsulated by its context.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** create a new service once the service begins to exceed that singular purpose.
|
||||
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** When a service has multiple responsibilities, it becomes difficult to test.
|
||||
@ -1758,7 +1784,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
**Why?** This is ideal when a service is sharing methods and has no state, or state that must be shared.
|
||||
**Why?** This is ideal when a service is sharing methods or state.
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
@ -1768,7 +1794,7 @@ a(href="#toc") Back to top
|
||||
`style-guide/ts/07-03/app/app.component.ts,
|
||||
style-guide/ts/07-03/app/heroes/hero-list/hero-list.component.ts`,
|
||||
'',
|
||||
`app/app.component.ts,
|
||||
`app/app.component.ts,
|
||||
app/heroes/hero-list/hero-list.component.ts`)
|
||||
:marked
|
||||
|
||||
@ -1782,7 +1808,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** use the `@Injectable` class decorator instead of the `@Inject` parameter decorator when we are using types as tokens for the dependencies of a service.
|
||||
**Do** use the `@Injectable` class decorator instead of the `@Inject` parameter decorator when using types as tokens for the dependencies of a service.
|
||||
|
||||
.s-why
|
||||
:marked
|
||||
@ -1810,8 +1836,8 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** refactor logic for making data operations and interacting with data to a service.
|
||||
|
||||
**Do** refactor logic for making data operations and interacting with data to a service.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** make data services responsible for XHR calls, local storage, stashing in memory, or any other data operations.
|
||||
@ -1850,7 +1876,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-why.s-why-last
|
||||
:marked
|
||||
**Why?** We will avoid unintentionally not calling the hook if we misspell the method.
|
||||
**Why?** We avoid unintentionally not calling the hook if we misspell the method.
|
||||
|
||||
+makeExample('style-guide/ts/09-01/app/heroes/shared/hero-button/hero-button.component.avoid.ts', 'example', 'app/heroes/shared/hero-button/hero-button.component.ts')(avoid=1)
|
||||
:marked
|
||||
@ -1863,7 +1889,7 @@ a(href="#toc") Back to top
|
||||
.l-main-section
|
||||
:marked
|
||||
## Routing
|
||||
|
||||
|
||||
Client-side routing is important for creating a navigation flow between a component tree hierarchy, and composing components that are made of many other child components.
|
||||
|
||||
a(href="#toc") Back to top
|
||||
@ -1884,7 +1910,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** focus the logic in the component router to the routing aspects and its target components.
|
||||
**Do** focus the logic in the component router to the routing aspects and its target components.
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
@ -1943,7 +1969,7 @@ a(href="#toc") Back to top
|
||||
|
||||
.s-rule.consider
|
||||
:marked
|
||||
**Consider** using [snippets](https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2) for [Visual Studio Code](https://code.visualstudio.com/) that follow these styles and guidelines.
|
||||
**Consider** using [snippets](https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2) for [Visual Studio Code](https://code.visualstudio.com/) that follow these styles and guidelines.
|
||||
|
||||
:marked
|
||||
[](https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user