12373
12373
com
https://textbookfull.com/product/ang-book-2-the-complete-
book-on-angular-2-1st-edition-nate-murray/
OR CLICK HERE
DOWLOAD EBOOK
https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-nate-murray/
textbookfull.com
https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-5-nathan-murray/
textbookfull.com
https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-9-nathan-murray/
textbookfull.com
https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-11-felipe-coury/
textbookfull.com
ng book The Complete Book on AngularJS 1st Edition Ari
Lerner
https://textbookfull.com/product/ng-book-the-complete-book-on-
angularjs-1st-edition-ari-lerner/
textbookfull.com
https://textbookfull.com/product/angular-2-cookbook-frisbie/
textbookfull.com
https://textbookfull.com/product/angular-2-ui-development-kasagoni/
textbookfull.com
https://textbookfull.com/product/marquise-mansion-on-the-hill-
book-2-1st-edition-chashiree-m-m-k-moore-m/
textbookfull.com
https://textbookfull.com/product/kovana-outsider-book-2-1st-edition-
aiden-phoenix/
textbookfull.com
ng-book 2
Felipe Coury, Ari Lerner, Nate Murray, & Carlos Taborda
© 2015 - 2016 Felipe Coury, Ari Lerner, Nate Murray, & Carlos Taborda
Contents
Book Revision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Prerelease . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Bug Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chat With The Community! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Be notified of updates via Twitter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
We’d love to hear from you! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Angular 2 is built in TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
What do we get with TypeScript? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Trying it out with a REPL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Built-in types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Fat Arrow Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Template Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Wrapping up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Component inputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Component outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Emitting Custom Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Writing the ProductsList Controller Class . . . . . . . . . . . . . . . . . . . . . . . . 97
Writing the ProductsList View Template . . . . . . . . . . . . . . . . . . . . . . . . 98
The Full ProductsList Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
The ProductRow Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
ProductRow Component Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . 103
ProductRow Component Definition Class . . . . . . . . . . . . . . . . . . . . . . . . . 103
ProductRow template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
ProductRow Full Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
The ProductImage Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
The PriceDisplay Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
The ProductDepartment Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
NgModule and Booting the App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Booting the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
The Completed Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
A Word on Data Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Using @angular/http . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
import from @angular/http . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
A Basic Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Building the SimpleHTTPComponent @Component . . . . . . . . . . . . . . . . . . . . . 157
Building the SimpleHTTPComponent template . . . . . . . . . . . . . . . . . . . . . . . 157
Building the SimpleHTTPComponent Controller . . . . . . . . . . . . . . . . . . . . . . 158
Full SimpleHTTPComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Writing a YouTubeSearchComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Writing a SearchResult . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Writing the YouTubeService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Writing the SearchBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Writing SearchResultComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Writing YouTubeSearchComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
@angular/http API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Making a POST request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
PUT / PATCH / DELETE / HEAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
RequestOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Why Do We Need Routing? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
How client-side routing works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
The beginning: using anchor tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
The evolution: HTML5 client-side routing . . . . . . . . . . . . . . . . . . . . . . . . 189
Writing our first routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Components of Angular 2 routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Installing our Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
RouterOutlet using <router-outlet> . . . . . . . . . . . . . . . . . . . . . . . . . . 193
RouterLink using [routerLink] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
CONTENTS
DoCheck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
AfterContentInit, AfterViewInit, AfterContentChecked and AfterViewChecked . . . . 484
Advanced Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
Rewriting ngIf - ngBookIf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
Rewriting ngFor - ngBookRepeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
Change Detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Customizing Change Detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
Zones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Observables and OnPush . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
Testing . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Test driven? . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
End-to-end vs. Unit Testing . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Testing Tools . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Jasmine . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Karma . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Writing Unit Tests . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Angular Unit testing framework . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Setting Up Testing . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
Testing Services and HTTP . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
HTTP Considerations . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Stubs . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Mocks . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Http MockBackend . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
TestBed.configureTestingModule and Providers . . . . . . . . . . . . . . . . . . . . 527
Testing getTrack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
Testing Routing to Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
Creating a Router for Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
Mocking dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Spies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Back to Testing Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
fakeAsync and advance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
inject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
Testing ArtistComponent’s Initialization . . . . . . . . . . . . . . . . . . . . . . . . . 544
Testing ArtistComponent Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Testing ArtistComponent DOM Template Values . . . . . . . . . . . . . . . . . . . . . 547
Testing Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
Creating a ConsoleSpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
Installing the ConsoleSpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
Configuring the Testing Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
Testing The Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
Refactoring Our Form Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
CONTENTS
Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 39 - 2016-09-03 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 38 - 2016-08-29 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 37 - 2016-08-02 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 36 - 2016-07-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 35 - 2016-06-30 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 34 - 2016-06-15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624
Revision 33 - 2016-05-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624
Revision 32 - 2016-05-06 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624
Revision 31 - 2016-04-28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 30 - 2016-04-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 29 - 2016-04-08 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 28 - 2016-04-01 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 27 - 2016-03-25 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 26 - 2016-03-24 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 25 - 2016-03-21 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 24 - 2016-03-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 23 - 2016-03-04 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 22 - 2016-02-24 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Revision 21 - 2016-02-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Revision 20 - 2016-02-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Revision 19 - 2016-02-04 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 18 - 2016-01-29 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 17 - 2016-01-28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 16 - 2016-01-14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 15 - 2016-01-07 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 14 - 2015-12-23 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
Revision 13 - 2015-12-17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
Revision 12 - 2015-11-16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
Revision 11 - 2015-11-09 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629
Revision 10 - 2015-10-30 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 9 - 2015-10-15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 8 - 2015-10-08 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 7 - 2015-09-23 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 6 - 2015-08-28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631
Revision 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631
Revision 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631
Revision 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631
CONTENTS 1
Book Revision
Revision 39 - Covers up to Angular 2 (2.0.0-rc.6, 2016-09-03)
Prerelease
This book is a prerelease version and a work-in-progress.
Bug Reports
If you’d like to report any bugs, typos, or suggestions just email us at: us@fullstack.io¹.
⁵
⁵mailto:carlos@ng-book.com
Writing your First Angular 2 Web
Application
Simple Reddit Clone
In this chapter we’re going to build an application that allows the user to post an article (with a
title and a URL) and then vote on the posts.
You can think of this app as the beginnings of a site like Reddit⁶ or Product Hunt⁷.
In this simple app we’re going to cover most of the essentials of Angular 2 including:
By the time you’re finished with this chapter you’ll have a good grasp on how to build basic Angular
2 applications.
Here’s a screenshot of what our app will look like when it’s done:
⁶http://reddit.com
⁷http://producthunt.com
Writing your First Angular 2 Web Application 2
Completed application
First, a user will submit a new link and after submitting the users will be able to upvote or downvote
each article. Each link will have a score and we can vote on which links we find useful.
Writing your First Angular 2 Web Application 3
In this project, and throughout the book, we’re going to use TypeScript. TypeScript is a superset of
JavaScript ES6 that adds types. We’re not going to talk about TypeScript in depth in this chapter, but
if you’re familiar with ES5 (“normal” javascript) / ES6 (ES2015) you should be able to follow along
without any problems.
We’ll go over TypeScript more in depth in the next chapter. So don’t worry if you’re having
trouble with some of the new syntax.
Writing your First Angular 2 Web Application 4
Getting started
TypeScript
To get started with TypeScript, you’ll need to have Node.js installed. There are a couple of different
ways you can install Node.js, so please refer to the Node.js website for detailed information:
https://nodejs.org/download/⁸ .
Do I have to use TypeScript? No, you don’t have to use TypeScript to use Angular 2, but
you probably should. ng2 does have an ES5 API, but Angular 2 is written in TypeScript
and generally that’s what everyone is using. We’re going to use TypeScript in this book
because it’s great and it makes working with Angular 2 easier. That said, it isn’t strictly
required.
Once you have Node.js setup, the next step is to install TypeScript. Make sure you install at least
version 1.7 or greater. To install it, run the following npm command:
npm is installed as part of Node.js. If you don’t have npm on your system, make sure you
used a Node.js installer that includes it.
Example Project
Now that you have your environment ready, let’s start writing our first Angular2 application!
Open up the code download that came with this book and unzip it. In your terminal, cd into the
first_app/angular2-reddit-base directory:
1 $ cd first_app/angular2-reddit-base
⁸https://nodejs.org/download/
⁹https://www.cygwin.com/
Writing your First Angular 2 Web Application 5
If you’re not familiar with cd, it stands for “change directory”. If you’re on a Mac try the
following:
1. Open up /Applications/Utilities/Terminal.app
2. Type cd, without hitting enter
3. In the Finder, Drag the first_app/angular2-reddit-base folder on to your termi-
nal window
4. Hit Enter Now you are cded into the proper directory and you can move on to the
next step!
1 $ npm install
Create a new index.html file in the root of the project and add some basic structure:
1 <!doctype html>
2 <html>
3 <head>
4 <title>Angular 2 - Simple Reddit</title>
5 </head>
6 <body>
7 </body>
8 </html>
1 .
2 |-- README.md // A helpful readme
3 |-- index.html // Your index file
4 |-- index-full.html // Sample index file
5 |-- node_modules/ // installed dependencies
6 |-- package.json // npm configuration
7 |-- resources/ // images etc.
8 |-- styles.css // stylesheet
9 |-- tsconfig.json // compiler configuration
10 `-- tslint.json // code-style guidelines
Angular 2 itself is a JavaScript file. So we need to add a script tag to our index.html document
to include it. But Angular has some dependencies itself:
Writing your First Angular 2 Web Application 6
Angular’s Dependencies
You don’t strictly need to understand these dependencies in-depth in order to use Angular
2, but you do need to include them. Feel free to skip this section if you’re not that interested
in the dependencies, but make sure you copy and paste these script tags.
• core-js
• zone.js
• reflect-metadata
• SystemJS
1 <script src="node_modules/core-js/client/shim.min.js"></script>
2 <script src="node_modules/zone.js/dist/zone.js"></script>
3 <script src="node_modules/reflect-metadata/Reflect.js"></script>
4 <script src="node_modules/systemjs/dist/system.src.js"></script>
Notice that we’re loading these .js files directly from a directory called node_-
modules. The node_modules directory will be created when you run npm install. If
you don’t have a node_modules directory, make sure your shell was “in” the directory
angular2-reddit-base (e.g. by using cd angular2-reddit-base) when you typed npm
install.
ES6 provides shims so that legacy JavaScript engines behave as closely as possible to ECMAScript 6.
This shim isn’t strictly needed for newer versions of Safari, Chrome, etc. but it is required for older
versions of IE.
What’s a shim? Perhaps you’ve heard about shims or polyfills and you’re not sure what
they are. A shim is code that helps adapt between cross browsers to a standardized behavior.
For instance, check out this ES6 Compatibility Table¹⁰. Not every browser is completely
compatible with every feature. By using different shims we’re able to get standardized
behavior across different browsers (and environments).
See also: What is the difference between a shim and a polyfill?¹¹
¹⁰https://kangax.github.io/compat-table/es6/
¹¹http://www.2ality.com/2011/12/shim-vs-polyfill.html
Writing your First Angular 2 Web Application 7
Zones
Zone.js¹³ is an advanced topic that we don’t need to worry about much here. For know, just know
that it is a library used by Angular, primarily for detecting changes to data. (If you’re coming from
Angular 1, you can think of zones as an automatic version of $digest. If you’re not coming from
Angular 1, you can ignore it for now.)
Reflect Metadata
Angular itself was written in Typescript, and Typescript provides annotations for adding metadata
to code. Roughly speaking, the reflect-metadata package is a polyfill that lets us use this metadata.
SystemJS
SystemJS is a module loader. That is, it helps us create modules and resolve dependencies. Module
loading in browser-side javascript is surprisingly complicated and SystemJS makes the process much
easier.
1 <!doctype html>
2 <html>
3 <head>
4 <title>Angular 2 - Simple Reddit</title>
5 <!-- Libraries -->
6 <script src="node_modules/core-js/client/shim.min.js"></script>
7 <script src="node_modules/zone.js/dist/zone.js"></script>
8 <script src="node_modules/reflect-metadata/Reflect.js"></script>
9 <script src="node_modules/systemjs/dist/system.src.js"></script>
10
11 </head>
12 <body>
13 </body>
14 </html>
Adding CSS
We also want to add some CSS styling so that our app isn’t completely unstyled. Let’s include two
stylesheets as well:
¹²https://github.com/zloirock/core-js
¹³https://github.com/angular/zone.js/
Writing your First Angular 2 Web Application 8
1 <!doctype html>
2 <html>
3 <head>
4 <title>Angular 2 - Simple Reddit</title>
5 <!-- Libraries -->
6 <script src="node_modules/core-js/client/shim.min.js"></script>
7 <script src="node_modules/zone.js/dist/zone.js"></script>
8 <script src="node_modules/reflect-metadata/Reflect.js"></script>
9 <script src="node_modules/systemjs/dist/system.src.js"></script>
10
11 <!-- Stylesheet -->
12 <link rel="stylesheet" type="text/css"
13 href="resources/vendor/semantic.min.css">
14 <link rel="stylesheet" type="text/css" href="styles.css">
15 </head>
16 <body>
17 </body>
18 </html>
For this project we’re going to be using Semantic-UI¹⁴ to help with the styling. Semantic-UI
is a CSS framework, similar to Foundation or Twitter Bootstrap. We’ve included it in the
sample code download so all you need to do is add the link tag.
Notice that we suffix our TypeScript file with .ts instead of .js The problem is our browser
doesn’t know how to interpret TypeScript files. To solve this, we’ll compile our .ts to a
.js file in just a few minutes.
¹⁴http://semantic-ui.com/
Writing your First Angular 2 Web Application 9
code/first_app/angular2-reddit-base/app.ts
1 /**
2 * A basic hello-world Angular 2 app
3 */
4 import {
5 NgModule,
6 Component
7 } from '@angular/core';
8 import { BrowserModule } from '@angular/platform-browser';
9 import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
10
11 @Component({
12 selector: 'hello-world',
13 template: `
14 <div>
15 Hello world
16 </div>
17 `
18 })
19 class HelloWorld {
20 }
21
22 @NgModule({
23 declarations: [ HelloWorld ],
24 imports: [ BrowserModule ],
25 bootstrap: [ HelloWorld ],
26 })
27 class HelloWorldAppModule {}
28
29 platformBrowserDynamic().bootstrapModule(HelloWorldAppModule);
This snippet may seem scary at first, but don’t worry. We’re going to walk through it step by step.
The import statements define the modules we want to use to write our code. Here we’re importing
four things: NgModule, Component, BrowserModule, and platformBrowserDynamic. We’ll be going
over each of these things in depth, so don’t worry if you aren’t sure what they do yet.
We import NgModule, Component from the module "@angular/core". The "@angular/core" portion
tells our program where to find the dependencies that we’re looking for.
Similarly, we import BrowserModule from the module "@angular/platform-browser" and plat-
formBrowserDynamic from the module "@angular/platform-browser-dynamic". We’ll talk about
these in a minute.
Writing your First Angular 2 Web Application 10
Notice that the structure of this import is of the format import { things } from wherever. In the
{ things } part what we are doing is called destructuring. Destructuring is a feature provided ES6
and we talk more about it in the next chapter.
The idea with the import is a lot like import in Java or require in Ruby: we’re pulling in these
dependencies from another module and making these dependencies available for use in this file.
Making a Component
One of the big ideas behind Angular 2 is the idea of components.
In our Angular apps we write HTML markup that becomes our interactive application. But the
browser only knows so many tags: the built-ins like <select> or <form> or <video> all have
functionality defined by our browser creator. But what if we want to teach the browser new tags?
What if we wanted to have a <weather> tag that shows the weather? Or what if we wanted to have
a <login> tag that creates a login panel?
That is the idea behind components: we teach the browser new tags that have new functionality.
If you have a background in Angular 1, Components are the new version of directives.
Let’s create our very first component. When we have this component written, we will be able to use
it in our HTML document like so:
1 <hello-world></hello-world>
So how do we actually define a new Component? A basic Component has two parts:
1. A Component annotation
2. A component definition class
1 @Component({
2 // ...
3 })
Writing your First Angular 2 Web Application 11
What is going on here? Well if you have a Java background it may look familiar to you: they are
annotations.
Think of annotations as metadata added to your code. When we use @Component on the HelloWorld
class, we are “decorating” the HelloWorld as a Component.
We want to be able to use this component in our markup by using a <hello-world> tag. To do that
we configure the @Component and specify the selector as hello-world.
1 @Component({
2 selector: 'hello-world'
3 })
If you’re familiar with CSS selectors, XPath, or JQuery selectors you’ll know that there are lots of
ways to configure a selector. Angular adds its own special sauce to the selector mix, and we’ll cover
that later on. For now, just know that in this case we’re defining a new tag.
The selector property here indicates which DOM element this component is going to use. This way
if we have any <hello-world></hello-world> tag within a template, it will be compiled using this
Component class.
Adding a template
We can add a template to our @Component by passing the template option:
1 @Component({
2 selector: 'hello-world',
3 template: `
4 <div>
5 Hello world
6 </div>
7 `
8 })
Notice that we’re defining our template string between backticks (` … `). This is a new (and
fantastic) feature of ES6 that allows us to do multiline strings. Using backticks for multiline strings
makes it easy to put templates inside your code files.
Writing your First Angular 2 Web Application 12
Should I really be putting templates in my code files? The answer is: it depends. For
a long time the commonly held belief was that you should keep your code and templates
separate. While this might be easier for some teams, for some projects it adds overhead
because you have switch between a lot of files.
Personally, if my templates are shorter than a page I much prefer to have the templates
alongside the code (that is, within the .ts file). When I can see both the logic and the view
together and it’s easy to understand how they interact with one another.
The biggest drawback to putting your views inlined with your code is that many editors
don’t support syntax highlighting of the internal strings (yet). Hopefully we’ll see more
editors supporting syntax highlighting HTML within template strings soon.
If you want to separate your template into a different file you can use the templateUrl key
to specify the URL of a template that will be loaded. More on this later.
code/first_app/angular2-reddit-base/app.ts
22 @NgModule({
23 declarations: [ HelloWorld ],
24 imports: [ BrowserModule ],
25 bootstrap: [ HelloWorld ],
26 })
27 class HelloWorldAppModule {}
28
29 platformBrowserDynamic().bootstrapModule(HelloWorldAppModule);
The first thing we see is an @NgModule annotation. Like all annotations, this @NgModule( ... ) code
adds metadata to the class immediately following (HelloWorldAppModule).
Writing your First Angular 2 Web Application 13
Our @NgModule annotation has three keys: declarations, imports, and bootstrap.
declarations defines the components in this module. In this case, we just have one, but you often
have several.
imports describes which dependencies this module has. We’re creating a browser app, so we want
to import the BrowserModule.
bootstrap tells Angular that when this module is used to bootstrap an app, we and to load the
HelloWorld component as the top-level component.
Now that we have our @NgModule defined, we can boot the app. The last line does this.
Remember that Angular can run on different platforms and so when we say platformBrowser-
Dynamic() we’re telling Angular that we’re using a browser and we want to compile Angular
“dynamically” (e.g. when we open the page in our browser vs. ahead-of-time compiling, which
we’ll talk more about much later).
Now that we have a platform, we call .bootstrapModule() and give it our HelloWorldAppModule
as the starting point.
Once the application is bootstrapped, the HelloWorld component will be rendered where the <hello-
world></hello-world> snippet is on the index.html file. Let’s try it out!
[3] Thucyd. ii, 63. τῆς τε πόλεως ὑμᾶς εἰκὸς τῷ τιμωμένῳ ἀπὸ τοῦ ἄρχειν,
ᾧπερ ἅπαντες ἀγάλλεσθε, βοηθεῖν, καὶ μὴ φεύγειν τοὺς πόνους, ἢ μηδὲ τὰς τιμὰς
διώκειν, etc.
[7] The island of Kythêra was conquered by the Athenians from Sparta in 425
B.C., and the annual tribute then imposed upon it was four talents (Thucyd. iv,
57). In the Inscription No. 143, ap. Boeckh, Corp. Inscr., we find some names
enumerated of tributary towns, with the amount of tribute opposite to each, but
the stone is too much damaged to give us much information. Tyrodiza, in Thrace,
paid one thousand drachms: some other towns, or junctions of towns, not clearly
discernible, are rated at one thousand, two thousand, three thousand drachms,
one talent, and even ten talents. This inscription must be anterior to 415 B.C.,
when the tribute was converted into a five per cent. duty upon imports and
exports: see Boeckh, Public Econ. of Athens, and his Notes upon the above-
mentioned Inscription.
It was the practice of Athens not always to rate each tributary city separately,
but sometimes to join several in one collective rating; probably each responsible
for the rest. This seems to have provoked occasional remonstrances from the
allies, in some of which the rhetor, Antipho, was employed to furnish the speech
which the complainants pronounced before the dikastery: see Antipho ap.
Harpokration, v. Ἀπόταξις—Συντελεῖς. It is greatly to be lamented that the
orations composed by Antipho, for the Samothrakians and Lindians,—the latter
inhabiting one of the three separate towns in the island of Rhodes,—have not
been preserved.
[8] Xenophon, Anab. vii, 1, 27. οὐ μεῖον χιλίων ταλάντων: compare Boeckh,
Public Econ. of Athens, b. iii, ch. 7, 15, 19.
[12] Thucyd. i, 80. The foresight of the Athenian people, in abstaining from
immediate use of public money and laying it up for future wants, would be still
more conspicuously demonstrated, if the statement of Æschinês, the orator, were
true, that they got together seven thousand talents between the peace of Nikias
and the Sicilian expedition. M. Boeckh believes this statement, and says: “It is not
impossible that one thousand talents might have been laid by every year, as the
amount of tribute received was so considerable.” (Public Economy of Athens, ch.
xx. p. 446, Eng. Trans.) I do not believe the statement: but M. Boeckh and
others, who do admit it, ought in fairness to set it against the many remarks
which they pass in condemnation of the democratical prodigality.
[13] Thucyd. i. 122-143; ii, 13. The πεντηκοστὴ, or duty of two per cent.
upon imports and exports at the Peiræus, produced to the state a revenue of
thirty-six talents in the year in which it was farmed by Andokidês, somewhere
about 400 B.C., after the restoration of the democracy at Athens from its defeat
and subversion at the close of the Peloponnesian war (Andokidês de Mysteriis, c.
23, p. 65). This was at a period of depression in Athenian affairs, and when trade
was doubtless not near so good as it had been during the earlier part of the
Peloponnesian war.
It seems probable that this must have been the most considerable permanent
source of Athenian revenue next to the tribute; though we do not know what rate
of customs-duty was imposed at the Peiræus during the Peloponnesian war.
Comparing together the two passages of Xenophon (Republ. Ath. 1, 17, and
Aristophan. Vesp. 657), we may suppose that the regular and usual rate of duty
was one per cent. or one ἑκατοστὴ,—while in case of need this may have been
doubled or tripled.—τὰς πολλὰς ἑκατοστάς, (see Boeckh, b. iii, chs. 1-4, pp. 298-
318, Eng. Trans.) The amount of revenue derived even from this source, however,
can have borne no comparison to the tribute.
[14] By Periklês, Thucyd. ii, 63. By Kleon, Thucyd. iii, 37. By the envoys at
Melos, v, 89. By Euphemus, vi, 85. By the hostile Corinthians, i, 124 as a matter
of course.
[18] Xenophon, Rep. Ath. ii, 16. τὴν μὲν οὐσίαν ταῖς νήσοις παρατίθενται,
πιστεύοντες τῇ ἀρχῇ τῇ κατὰ θάλασσαν· τὴν δὲ Ἀττικὴν γῆν περιορῶσι
τεμνομένην, γιγνώσκοντες ὅτι εἰ αὐτὴν ἐλεήσουσιν, ἑτέρων ἀγαθῶν μειζόνων
στερήσονται.
Compare also Xenophon (Memorabil. ii, 8, 1, and Symposion, iv, 31).
[19] See the case of the free laborer and the husbandman at Naxos, Plato,
Euthyphro, c. 3.
[21] Thucyd. iv, 105; Marcellinus, Vit. Thucyd. c. 19. See Rotscher, Leben des
Thukydides, ch. i, 4, p. 96, who gives a genealogy of Thucydidês, as far as it can
be made out with any probability. The historian was connected by blood with
Miltiadês and Kimon, as well as with Olorus, king of one of the Thracian tribes,
whose daughter Hegesipylê was wife of Miltiadês, the conqueror of Marathon. In
this manner, therefore, he belonged to one of the ancient heroic families of
Athens, and even of Greece, being an Ækid through Ajax and Philæus (Marcellin.
c. 2).
[24] Diodor. xii, 11, 12; Strabo. vi, 264: Plutarch, Periklês, c. 22.
[25] The Athenians pretended to no subject allies beyond the Ionian gulf,
Thucyd. vi, 14: compare vi, 45, 104; vii, 34. Thucydidês does not even mention
Thurii, in his catalogue of the allies of Athens at the beginning of the
Peloponnesian war (Thucyd. ii, 15).
[27] Compare the speech of Nikias, in reference to the younger citizens and
partisans of Alkibiadês sitting together near the latter in the assembly,—οὓς ἐγὼ
ὁρῶν νῦν ἐνθάδε τῷ αὐτῷ ἀνδρὶ π α ρ α κ ε λ ε υ σ τ ο ὺ ς κ α θ η μ έ ν ο υ ς φοβοῦμαι,
καὶ τοῖς πρεσβυτέροις ἀντιπαρακελεύομαι μὴ καταισχυνθῆναι, εἴ τῴ τις
παρακάθηται τῶνδε, etc. (Thucyd. vi, 13.) See also Aristophanês, Ekklesiaz. 298,
seq., about partisans sitting near together.
[29] Plutarch, Periklês, c. 11. ἡ δ᾽ ἐκείνων ἅμιλλα καὶ φιλοτιμία τῶν ἀνδρῶν
βαθυτάτην τομὴν τεμοῦσα τῆς πόλεως, τὸ μὲν δῆμον, τὸ δ᾽ ὀλίγους ἐποίησε
καλεῖσθαι.
[37] See Dikæarchus, Vit. Græciæ, Fragm. ed. Fuhr. p. 140: compare the
description of Platæa in Thucydidês, ii, 3.
All the older towns now existing in the Grecian islands are put together in this
same manner,—narrow, muddy, crooked ways,—few regular continuous lines of
houses: see Ross, Reisen in den Griechischen Inseln, Letter xxvii, vol. ii, p. 20.
[40] Leake, Topography of Athens, Append. ii and iii, pp. 328-336, 2d edit.
[41] See Leake, Topography of Athens, 2d ed. p. 111, Germ. transl. O. Müller
(De Phidiæ Vitâ, p. 18) mentions no less than eight celebrated statues of Athênê,
by the hand of Pheidias,—four in the acropolis of Athens.
[42] Plutarch, Periklês, c. 13-15; O. Müller, De Phidiæ Vitâ, pp 34-60, also his
work, Archäologie der Kunst, sects. 108-113.
[43] Thucyd. i, 80. καὶ τοῖς ἄλλοις ἅπασιν ἄριστα ἐξήρτυνται, πλούτῳ τε ἰδίῳ
καὶ δημοσίῳ καὶ ναυσὶ καὶ ἵπποις καὶ ὅπλοις, καὶ ὄχλῳ ὅσος οὐκ ἐν ἄλλῳ ἑνί γε
χωρίῳ Ἑλληνικῷ ἐστὶν, etc.
[46] See Leake, Topography of Athens, Append. iii, p. 329, 2d ed. Germ.
transl. Colonel Leake, with much justice, contends that the amount of two
thousand and twelve talents, stated by Harpokration out of Philochorus as the
cost of the Propylæa alone, must be greatly exaggerated. Mr. Wilkins
(Atheniensia, p. 84) expresses the same opinion; remarking that the transport of
marble from Pentelikus to Athens is easy and on a descending road.
Demetrius Phalereus (ap. Cicer. de Officiis, ii, 17) blamed Periklês for the large
sum expended upon the Propylæa; nor is it wonderful that he uttered this
censure, if he had been led to rate the cost of them at two thousand and twelve
talents.
[49] Plutarch, Periklês, c. 17. Plutarch gives no precise date, and O. Müller
(De Phidiæ Vitâ, p. 9) places these steps for convocation of a congress before the
first war between Sparta and Athens and the battle of Tanagra,—i. e., before 460
B.C. But this date seems to me improbable: Thebes was not yet renovated in
power, nor had Bœotia as yet recovered from the fruits of her alliance with the
Persians; moreover, neither Athens nor Periklês himself seem to have been at that
time in a situation to conceive so large a project; which suits in every respect
much better for the later period, after the thirty years’ truce, but before the
Peloponnesian war.
[51] Thucyd. i, 115; Plutarch, Periklês, c. 25. Most of the statements which
appear in this chapter of Plutarch—over and above the concise narrative of
Thucydidês—appear to be borrowed from exaggerated party stories of the day.
We need make no remark upon the story, that Periklês was induced to take the
side of Milêtus against Samos, by the fact that Aspasia was a native of Milêtus.
Nor is it at all more credible that the satrap Pissuthnês, from good-will towards
Samos, offered Periklês ten thousand golden staters as an inducement to spare
Samos. It may perhaps be true however, that the Samian oligarchy, and those
wealthy men whose children were likely to be taken as hostages, tried the effect
of large bribes upon the mind of Periklês, to prevail upon him not to alter the
government.
[56] Plutarch, Periklês, c. 26. Plutarch seems to have had before him
accounts respecting this Samian campaign, not only from Ephorus, Stesimbrotus,
and Duris, but also from Aristotle: and the statements of the latter must have
differed thus far from Thucydidês, that he affirmed Melissus the Samian general
to have been victorious over Periklês himself, which is not to be reconciled with
the narrative of Thucydidês.
The Samian historian, Duris, living about a century after this siege, seems to
have introduced many falsehoods respecting the cruelties of Athens: see Plutarch,
l. c.
[57] It appears very improbable that this Thucydidês can be the historian
himself. If it be Thucydidês son of Melêsias, we must suppose him to have been
restored from ostracism before the regular time,—a supposition indeed noway
inadmissible in itself, but which there is nothing else to countenance. The author
of the Life of Sophoklês, as well as most of the recent critics, adopt this opinion.
On the other hand, it may have been a third person named Thucydidês; for
the name seems to have been common, as we might guess from the two words
of which it is compounded. We find a third Thucydidês mentioned viii, 92—a
native of Pharsalus: and the biographer, Marcellinus seems to have read of many
persons so called (Θουκύδιδαι πολλοὶ, p. xvi, ed. Arnold). The subsequent history
of Thucydidês son of Melêsias, is involved in complete obscurity. We do not know
the incident to which the remarkable passage in Aristophanês (Acharn. 703)
alludes,—compare Vespæ, 946: nor can we confirm the statement which the
Scholiast cites from Idomeneus, to the effect that Thucydidês was banished and
fled to Artaxerxes: see Bergk. Reliq. Com. Att. p. 61.
[58] Thucyd. i, 117; Diodor. xii, 27, 28; Isokratês, De Permutat. Or. xv, sect.
118; Cornel. Nepos, Vit. Timoth. c. 1.
The assertion of Ephorus (see Diodorus, xii, 28, and Ephori Fragm. 117 ed.
Marx, with the note of Marx) that Periklês employed battering machines against
the town, under the management of the Klazomenian Artemon, was called in
question by Herakleidês Ponticus, on the ground that Artemon was a
contemporary of Anakreon, near a century before: and Thucydidês represents
Periklês to have captured the town altogether by blockade.
[66] A short fragment remaining from the comic poet Eupolis (Κόλακες, Fr.
xvi, p. 493, ed. Meineke), attests the anxiety at Athens about the Samian war,
and the great joy when the island was reconquered: compare Aristophan. Vesp.
283.
[67] Thucyd. iii, 37; ii, 63. See the conference, at the island of Melos in the
sixteenth year of the Peloponnesian war (Thucyd. v, 89, seq.), between the
Athenian commissioners and the Melians. I think, however, that this conference is
less to be trusted as based in reality, than the speeches in Thucydidês generally,
—of which more hereafter.
[68] Thucyd. iii, 47. Νῦν μὲν γὰρ ὑμῖν ὁ δῆμος ἐν ἁπάσαις ταῖς πόλεσιν
εὔνους ἐστὶ, καὶ ἢ οὐ ξυναφίσταται τοῖς ὀλίγοις, ἢ ἐὰν βιασθῇ, ὑπάρχει τοῖς
ἀποστήσασι πολέμιος εὐθὺς, etc.
[69] See the striking observations of Thucydidês, iii, 82, 83; Aristotel. Politic.
v, 6, 9.
[71] Thucyd. viii, 9-14. He observes, also, respecting the Thasian oligarchy
just set up in lieu of the previous democracy by the Athenian oligarchical
conspirators who were then organizing the revolution of the Four Hundred at
Athens,—that they immediately made preparations for revolting from Athens,—
ξυνέβη οὖν αὐτοῖς μάλιστα ἃ ἐβούλοντο, τὴν πόλιν τε ἀκινδύνως ὀρθοῦσθαι, καὶ
τ ὸ ν ἐ ν α ν τ ι ω σ ό μ ε ν ο ν δ ῆ μ ο ν κ α τ α λ ε λ ύ σ θ α ι (viii, 64).
[74] Xenophon. Repub. Athen. iii, 5. πλὴν αἱ τάξεις τοῦ φόρου· τοῦτο δὲ
γίγνεται ὡς τὰ πολλὰ δι᾽ ἔτους πέμπτου.
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
textbookfull.com