402

dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 2: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 3: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SwitchingtoAngular2

Page 4: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TableofContents

SwitchingtoAngular2

Credits

Foreword

AbouttheAuthor

AbouttheReviewers

www.PacktPub.com

eBooks,discountoffers,andmore

Whysubscribe?

Preface

Whatthisbookcovers

Whatyouneedforthisbook

Whothisbookisfor

Conventions

Readerfeedback

Customersupport

Downloadingtheexamplecode

Errata

Piracy

Questions

1.GettingStartedwithAngular2

TheevolutionoftheWeb–timeforanewframework

TheevolutionofECMAScript

WebComponents

WebWorkers

LessonslearnedfromAngularJS1.xinthewild

Controllers

Scope

DependencyInjection

Server-siderendering

Page 5: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Applicationsthatscale

Templates

Changedetection

Summary

2.TheBuildingBlocksofanAngular2Application

AconceptualoverviewofAngular2

Changingdirectives

GettingtoknowAngular2components

Componentsinaction

ComponentsinAngular2

Pipes

Definingpipes

Changedetection

Classicalchangedetection

AngularJS1.xchangedetection

Inthezone.js

Simplifieddataflow

EnhancingAngularJS1.x’schangedetection

Understandingservices

Understandingthenewcomponent-basedrouter

Angular2routedefinitionsyntax

Summary

3.TypeScriptCrashCourse

IntroductiontoTypeScript

Compile-timetypechecking

BettersupportbytexteditorsandIDEs

There’sevenmoretoTypeScript

UsingTypeScript

InstallingTypeScriptwithnpm

RunningourfirstTypeScriptprogram

TypeScriptsyntaxandfeaturesintroducedbyES2015andES2016

Page 6: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ES2015arrowfunctions

UsingtheES2015andES2016classes

Definingvariableswithblockscope

Meta-programmingwithES2016decorators

Usingconfigurabledecorators

WritingmodularcodewithES2015

UsingtheES2015modulesyntax

Takingadvantageoftheimplicitasynchronousbehavior

Usingaliases

Importingallthemoduleexports

Defaultexports

ES2015moduleloader

ES2015andES2016recap

Takingadvantageofstatictyping

Usingexplicittypedefinitions

Thetypeany

UnderstandingthePrimitivetypes

TheEnumtypes

UnderstandingtheObjecttypes

TheArraytypes

TheFunctiontypes

Definingclasses

Usingaccessmodifiers

Defininginterfaces

Interfaceinheritance

Implementingmultipleinterfaces

FurtherexpressivenesswithTypeScriptdecorators

Writinggenericcodebyusingtypeparameters

Usinggenericfunctions

Havingmultipletypeparameters

WritinglessverbosecodewithTypeScript’stypeinference

Page 7: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Bestcommontype

Contextualtypeinference

Usingambienttypedefinitions

Usingpredefinedambienttypedefinitions

Customambienttypedefinitions

Definingts.dfiles

Summary

4.GettingStartedwithAngular2ComponentsandDirectives

TheHelloworld!applicationinAngular2

Settingupourenvironment

Installingourprojectrepository

PlayingwithAngular2andTypeScript

Diggingintotheindex

UsingAngular2directives

ThengFordirective

Improvedsemanticsofthedirectivessyntax

Declaringvariablesinsideatemplate

Usingsyntaxsugarintemplates

DefiningAngular2directives

Settingthedirective’sinputs

Understandingthedirective’sconstructor

Betterencapsulationofdirectives

UsingAngular2’sbuilt-indirectives

Introducingthecomponent’sviewencapsulation

Implementingthecomponent’scontrollers

Handlinguseractions

Usingadirectives’inputsandoutputs

Findingoutdirectives’inputsandoutputs

Definingthecomponent’sinputsandoutputs

Passinginputsandconsumingtheoutputs

Eventbubbling

Page 8: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Renamingtheinputsandoutputsofadirective

Analternativesyntaxtodefineinputsandoutputs

ExplainingAngular2’scontentprojection

BasiccontentprojectioninAngular2

Projectingmultiplecontentchunks

Nestingcomponents

UsingViewChildrenandContentChildren

ViewChildversusContentChild

Hookingintothecomponent’slifecycle

Theorderofexecution

DefininggenericviewswithTemplateRef

Understandingandenhancingthechangedetection

Theorderofexecutionofthechangedetectors

Changedetectionstrategies

PerformanceboostingwithimmutabledataandOnPush

UsingimmutabledatastructuresinAngular

Summary

5.DependencyInjectioninAngular2

WhydoIneedDependencyInjection?

DependencyInjectioninAngular2

BenefitsofDIinAngular2

Configuringaninjector

Dependencyresolutionwithgeneratedmetadata

Instantiatinganinjector

Introducingforwardreferences

Configuringproviders

Usingexistingproviders

Definingfactoriesforinstantiatingservices

Childinjectorsandvisibility

Buildingahierarchyofinjectors

Configuringdependencies

Page 9: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Usingthe@Selfdecorator

Skippingtheselfinjector

Havingoptionaldependencies

Usingmultiproviders

UsingDIwithcomponentsanddirectives

Introducingtheelementinjectors

Declaringprovidersfortheelementinjectors

ExploringDIwithcomponents

viewProvidersversusproviders

UsingAngular’sDIwithES5

Summary

6.WorkingwiththeAngular2RouterandForms

Developingthe“Codersrepository”application

ExploringtheAngular2router

Definingtherootcomponentandbootstrappingtheapplication

UsingPathLocationStrategy

Configuringrouteswith@RouteConfig

UsingrouterLinkandrouter-outlet

Lazy-loadingwithAsyncRoute

UsingAngular2forms

Developingtemplate-drivenforms

Diggingintothetemplate-drivenform’smarkup

Usingthebuilt-informvalidators

Definingcustomcontrolvalidators

UsingselectinputswithAngular

UsingtheNgFormdirective

Two-waydata-bindingwithAngular2

Storingtheformdata

Listingallthestoreddevelopers

Summary

7.ExplainingPipesandCommunicatingwithRESTfulServices

Page 10: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Developingmodel-drivenformsinAngular2

Usingcompositionofcontrolvalidators

ExploringtheHTTPmoduleofAngular

UsingAngular’sHTTPmodule

Definingparameterizedviews

Definingnestedroutes

Transformingdatawithpipes

Developingstatelesspipes

UsingAngular’sbuilt-inpipes

Developingstatefulpipes

Usingstatefulpipes

UsingAngular’sAsyncPipe

UsingAsyncPipewithobservables

Summary

8.DevelopmentExperienceandServer-SideRendering

RunningapplicationsinWebWorkers

WebWorkersandAngular2

BootstrappinganapplicationrunninginWebWorker

MigratinganapplicationtoWebWorker

MakinganapplicationcompatiblewithWebWorkers

Initialloadofasingle-pageapplication

InitialloadofaSPAwithserver-siderendering

Server-siderenderingwithAngular2

Enhancingourdevelopmentexperience

TexteditorsandIDEs

Hotreloading

HotreloadinginAngular2

Bootstrappingaprojectwithangular-cli

Usingangular-cli

Angular2quickstarters

Angular2seed

Page 11: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Angular2Webpackstarter

Summary

Index

Page 12: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 13: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SwitchingtoAngular2

Page 14: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 15: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SwitchingtoAngular2Copyright©2016PacktPublishing

Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.

Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.

PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.

Firstpublished:March2016

Productionreference:1220316

PublishedbyPacktPublishingLtd.

LiveryPlace

35LiveryStreet

BirminghamB32PB,UK.

ISBN978-1-78588-620-1

www.packtpub.com

Page 16: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 17: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

CreditsAuthor

MinkoGechev

Reviewers

MiškoHevery

DanielLamb

CommissioningEditor

EdwardGordon

AcquisitionEditor

KirkD’costa

ContentDevelopmentEditor

ShwetaPant

TechnicalEditor

MohitaVyas

CopyEditor

AkshataLobo

ProjectCoordinator

KinjalBari

Proofreader

SafisEditing

Indexer

MariammalChettiyar

Graphics

DishaHaria

ProductionCoordinator

NileshMohite

CoverWork

NileshMohite

Page 18: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 19: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ForewordAngular2isstillAngular,justbetter.ItisstillbuiltonthesameprinciplesthatmadeyouloveAngularJS:aquickandpowerfulsolutiontobuildingSinglePageApplications.InAngular2,theapplicationsarefaster,morevisibletoSEOandmobile,andarecross-platformready.SowhilstAngular2hasimprovedmanyoftheconceptsoverAngularJS,thephilosophyremainstruetotheoriginalvision.

SwitchingtoAngular2isabookthatrecognizesthis.Minko’sbooksuccessfullyhelpsyoutoswitchyourthinkingfromAngularJS1.xtoAngular2.FromyourfirstinteractionswithAngular2tothelast,thecoreconceptsofAngulararemaintainedthroughout.ThisguidewillhelpyoutoswitchtoAngular’snewwayofdoingthings.Minkoguidesyouthroughthechangesandnewfeaturesthathavebeenintroduced—components,directives,TypeScript,thenewrouter,andeverythingelseyouneedtostartusingAngular2foryournextproject.

AsAngular2takesupthechallengesetbytoday’schangingwebdevelopmentlandscapeandbuildsonthelegacyofAngularJS,it’sincrediblyimportantfortheAngularcommunitythattherearehighqualitylearningmaterialssuchasMinko’sbooktohelpAngulardevelopersmakethatfirstswitchovertothefuture.

MiškoHevery

CreatorofAngularJSandAngular2

Page 20: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 21: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

AbouttheAuthorMinkoGechevisasoftwareengineerwhostronglybelievesinopensourcesoftware.Hehasdevelopednumeroussuchprojects,includingAngularJS1.xandAngular2styleguides,angular2-seed,astaticcodeanalyzerforAngular2projects,aspect.js,angular-aop,andmanyothers.HerunstrainingcoursesinJavaScript,Angular,andotherwebtechnologies.

Minkolovestoexperimentwiththeoreticalconceptsfromcomputerscienceandapplytheminpractice.HehasspokenaboutAngularandsoftwaredevelopmentatworldwideconferencesandmeetups,includingng-vegas,AngularConnect,ITWeekendKiev,AngularJS-SF,andAngularBerlin.

IwanttothankMiškoHeveryforhisgreatcontributionsinsoftwareengineeringandthetechnicalreviewofthisbook.Hehelpedmeprovideasprecisecontentaspossible.Tomakethecodesamplesforthebookeasytorun,Iusedangular2-seed.CorecontributoroftheprojectisLudovicHénin,whohelpedmakeitmuchmorethananAngular2starter.IalsowanttothanktoDanielLamb,RadoslavKirovandTeroParviainenwhogavemeextremelyvaluablefeedback!.

Icouldn’tcompletethebookwithoutthededicatedworkofthePacktPublishingteam.

Finally,IwanttothanktheteamatGoogleforgivingusAngular.Theyareaconstantinspiration.

Page 22: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 23: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

AbouttheReviewersMiškoHeveryisthecreatoroftheAngularJSframework.Hehasapassionformakingcomplexthingssimple.HecurrentlyworksatGoogle,buthaspreviouslyworkedatAdobe,SunMicrosystems,Intel,andXerox,wherehebecameanexpertinbuildingwebapplicationsinweb-relatedtechnologies,suchasJava,JavaScript,Flex,andActionScript.

DanielLambisaseniorsoftwaredevelopmentprofessionalandanauthorwhoenjoyssharingtheknowledgehehasgained,specializinginlarge-scalearchitectureandfrontendwebdevelopment.Hisworkoverthelast16yearshasenabledhundredsofmillionstoengageandinteractduringbillionsofvisits.

Page 24: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 25: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

www.PacktPub.com

Page 26: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

eBooks,discountoffers,andmoreDidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<[email protected]>formoredetails.

Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.

https://www2.packtpub.com/books/subscription/packtlib

DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcansearch,access,andreadPackt’sentirelibraryofbooks.

Page 27: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser

Page 28: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 29: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

PrefaceAngularJSisaJavaScriptdevelopmentframeworkthatmakesbuildingwebapplicationseasier.Itisusedtodayinlarge-scale,high-trafficwebsitesthatstrugglewithunderperformanceandportabilityissues,aswellasSEOunfriendlinessandcomplexityatscale.Angular2changesthese.

Itisthemodernframeworkyouneedtobuildperformantandrobustwebapplications.SwitchingtoAngular2isthequickestwaytogettogripswithAngular2,anditwillhelpyoutransitionintothebravenewworldofAngular2.

Bytheendofthebook,you’llbereadytostartbuildingquickandefficientAngular2applicationsthattakeadvantageofallthenewfeaturesonoffer.

Page 30: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WhatthisbookcoversChapter1,GettingstartedwithAngular2,kicksoffourjourneyintotheworldofAngular2.Itdescribesthemainreasonsbehindthedesigndecisionsoftheframework.Wewilllookintothetwomaindriversbehindtheshapeoftheframework—thecurrentstateoftheWebandtheevolutionoffrontenddevelopment.

Chapter2,TheBuildingBlocksofanAngular2Application,givesanoverviewofthecoreconceptsintroducedbyAngular2.We’llexplorehowthefoundationalbuildingblocksforthedevelopmentofapplicationsprovidedbyAngularJS1.xdifferfromtheonesinthelastmajorversionoftheframework.

Chapter3,TypeScriptCrashCourse,explainsthatalthoughAngular2islanguageagnostic,Google’srecommendationistotakeadvantageofthestatictypingofTypeScript.Inthischapter,you’lllearnalltheessentialsyntaxyouneedtodevelopAngular2applicationsinTypeScript!

Chapter4,GettingStartedwithAngular2ComponentsandDirectives,describesthecorebuildingblocksfordevelopingtheuserinterfaceofourapplications—directivesandcomponents.Wewilldiveintoconceptssuchasviewencapsulation,contentprojection,inputsandoutputs,changedetectionstrategies,andmore.We’lldiscussadvancedtopicssuchastemplatereferencesandspeedingupourapplicationsusingimmutabledata.

Chapter5,DependencyInjectioninAngular2,coversoneofthemostpowerfulfeaturesintheframework,whichwasinitiallyintroducedbyAngularJS1.x:itsdependencyinjectionmechanism.Itallowsustowritemoremaintainable,testable,andunderstandablecode.Bytheendofthischapter,wewillknowhowtodefinethebusinesslogicinservicesandgluethemtogetherwiththeUIthroughtheDImechanism.Wewillalsolookintosomemoreadvancedconcepts,suchastheinjectorshierarchy,configuringproviders,andmore.

Chapter6,WorkingwiththeAngular2RouterandForms,exploresthenewmoduleformanagingformsintheprocessofdevelopingareal-lifeapplication.Wewillalsoimplementapagethatshowstheenteredthroughtheformdata.Intheend,wewillgluetheindividualpagestogetherintoanapplicationbyusingthecomponent-basedrouter.

Chapter7,ExplainingPipesandCommunicatingwithRESTfulservices,divesintotherouterandtheformsmodulesindetail.Here,wewillexplorehowwecandevelopmodel-drivenformsanddefineparameterizedandchildroutes.WewillalsoexplaintheHTTPmoduleandseehowwecandeveloppureandimpurepipes.

Chapter8,SEOandAngular2intheRealWorld,exploressomeadvancedtopicsintheAngular2applicationdevelopment,suchasrunninganapplicationinWebWorkersandserver-siderendering.Inthesecondpartofthechapter,wewillexploretoolsthatcaneaseourdailylifeasdevelopers,suchasangular-cli,andangular2-seed,explaintheconceptofhotreloading,andmore.

Page 31: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 32: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WhatyouneedforthisbookAllyouneedtoworkthroughmostoftheexamplesinthisbookisasimpletexteditororanIDE,Node.js,TypeScriptinstalled,Internetaccess,andabrowser.

Eachchapterintroducesthesoftwarerequirementsforrunningtheprovidedsnippets.

Page 33: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 34: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WhothisbookisforDoyouwanttojumpinatthedeependofAngular2?Orperhapsyou’reinterestedinassessingthechangesbeforemovingover?Ifso,thenSwitchingtoAngular2isthebookforyou.

Togetthemostoutofthebook,you’llneedtohavebasicunderstandingofAngularJS1.xandhaveagoodunderstandingofJavaScript.NoknowledgeofthechangesmadetoAngular2isrequiredtofollowalong.

Page 35: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 36: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ConventionsInthisbook,youwillfindanumberoftextstylesthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestylesandanexplanationoftheirmeaning.

Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“Youshouldseethesameresult,butwithoutthetest.jsfilestoredonthedisk.”

Ablockofcodeissetasfollows:

@Injectable()

classSocket{

constructor(privatebuffer:Buffer){}

}

letinjector=Injector.resolveAndCreate([

provide(BUFFER_SIZE,{useValue:42}),

Buffer,

Socket

]);

injector.get(Socket);

Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:

letinjector=Injector.resolveAndCreate([

provide(BUFFER_SIZE,{useValue:42}),

Buffer,

Socket

]);

Eachcodesnippetwhichisintherepositorywiththecodefromthisbookstartswithacommentwithitscorrespondingfilelocation,relativetotheappdirectory:

//ch5/ts/injector-basics/forward-ref.ts

@Injectable()

classSocket{

constructor(privatebuffer:Buffer){…}

}

Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,forexample,inmenusordialogboxes,appearinthetextlikethis:“Whenthemarkupisrenderedontothescreen,allthattheuserwillseeisthelabel:Loading….”

NoteWarningsorimportantnotesappearinaboxlikethis.

TipTipsandtricksappearlikethis.

Page 37: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 38: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 39: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsusdeveloptitlesthatyouwillreallygetthemostoutof.

Tosendusgeneralfeedback,simplye-mail<[email protected]>,andmentionthebook’stitleinthesubjectofyourmessage.

Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideatwww.packtpub.com/authors.

Page 40: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 41: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.

Page 42: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesforthisbookfromGitHubathttps://github.com/mgechev/switching-to-angular2.

Youcandownloadthecodefilesbyfollowingthesesteps:

1. EntertheURLinyourbrowser’saddressbar.2. Clickonthe“DownloadZIP”buttonlocatedinthemid-rightpartofthescreen.

Youcanalsodownloadtheexamplecodefilesforthisbookfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.

Youcanalsodownloadthecodefilesbyfollowingthesesteps:

1. Loginorregistertoourwebsiteusingyoure-mailaddressandpassword.2. HoverthemousepointerontheSUPPORTtabatthetop.3. ClickonCodeDownloads&Errata.4. EnterthenameofthebookintheSearchbox.5. Selectthebookforwhichyou’relookingtodownloadthecodefiles.6. Choosefromthedrop-downmenuwhereyoupurchasedthisbookfrom.7. ClickonCodeDownload.

Oncethefileisdownloaded,pleasemakesurethatyouunziporextractthefolderusingthelatestversionof:

WinRAR/7-ZipforWindowsZipeg/iZip/UnRarXforMac7-Zip/PeaZipforLinuxChapters3and4containfurtherinformationfortheinstallationprocess.

Page 43: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataundertheErratasectionofthattitle.

Toviewthepreviouslysubmittederrata,gotohttps://www.packtpub.com/books/content/supportandenterthenameofthebookinthesearchfield.TherequiredinformationwillappearundertheErratasection.

Page 44: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

PiracyPiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.

Pleasecontactusat<[email protected]>withalinktothesuspectedpiratedmaterial.

Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.

Page 45: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

QuestionsIfyouhaveaproblemwithanyaspectofthisbook,youcancontactusat<[email protected]>,andwewilldoourbesttoaddresstheproblem.

Page 46: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 47: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Chapter1.GettingStartedwithAngular2OnSeptember18,2014,thefirstpubliccommitwaspushedtotheAngular2repository.Afewweekslater,atng-europe,IgorandTobiasfromthecoreteamgaveashortoverviewofwhatAngular2wasexpectedtobe.Thevisionatthattimewasfarfromfinal;however,onethingwascertain—thenewversionoftheframeworkwouldbeentirelydifferentfromAngularJS1.x.

Thisannouncementbroughtalotofquestionsandcontroversy.Thereasonsbehindthedrasticchangeswerequiteclear—AngularJS1.xwasnolongerabletotakefulladvantageoftheevolvedWebandtocompletelysatisfytherequirementsoflarge-scaleJavaScriptapplications.AnewframeworkwouldletAngulardeveloperscapitalizeondevelopmentsinwebtechnologyinsimplerandmoredirectways.Yet,peoplewereconcerned.Oneofthebiggestnightmareswithbackwardincompatibilityfordevelopersisthemigrationoftheircurrentcodebasestothenewversionofthethird-partysoftwaretheyuse.InAngular’scase,afterthatfirstannouncement,migrationlookeddaunting,evenimpossible.Later,atng-conf2015andng-vegas,differentmigrationstrategieswereintroduced.TheAngularcommunitycametogetherandsharedadditionalideas,anticipatingthebenefitsofAngular2whilepreservingthethingslearnedfromAngularJS1.x.

Thisbookisapartofthatproject.MakingtheupgradetoAngular2isnon-trivial,butitisworthit.ThemaindriversbehindthedrasticchangesinAngular2anditslackofbackwardcompatibilityaretheevolutionoftheWeb,andthelessonslearnedfromtheusageofAngularJS1.xinthewild.SwitchingtoAngular2willhelpyoutolearnthenewframeworkbyunderstandinghowwegothereandwhyAngular’snewfeaturesmakeintuitivesenseforthemodernWebinbuildinghigh-performance,scalable,single-pageapplications.

Page 48: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TheevolutionoftheWeb–timeforanewframeworkInthelastcoupleofyears,theWebhasevolvedinbigsteps.DuringtheimplementationofECMAScript5,theECMAScript6standardstarteditsdevelopment(nowknownasECMAScript2015orES2015).ES2015introducedmanychangesinthelanguagesuchasaddingbuilt-inlanguagesupportformodules,blockscopevariabledefinition,andalotofsyntacticalsugar,suchasclassesanddestructuring.

Meanwhile,WebComponentswereinvented.WebComponentsallowustodefinecustomHTMLelementsandattachbehaviortothem.SinceitishardtoextendtheexistingHTMLelementswithnewones(suchasdialogs,charts,grids,andmore)mostlybecauseofthetimerequiredforconsolidationandstandardizationoftheirAPIs,abettersolutionistoallowdeveloperstoextendtheexistingelementsthewaytheywant.WebComponentsprovideuswithanumberofbenefits,includingbetterencapsulation,bettersemanticsofthemarkupweproduce,bettermodularity,andeasiercommunicationbetweendevelopersanddesigners.

WeknowthatJavaScriptisasingle-threadedlanguage.Initially,itwasdevelopedforsimpleclient-sidescripting,butovertime,itsrolehasshiftedquiteabit.NowwithHTML5,wehavedifferentAPIsthatallowaudioandvideoprocessing,communicationwithexternalservicesthroughatwo-directionalcommunicationchannel,transferringandprocessingbigchunksofrawdata,andmore.Alltheseheavycomputationsinthemainthreadmaycreateapooruserexperience.Theymayintroducefreezingoftheuserinterfacewhentime-consumingcomputationsarebeingperformed.ThisledtothedevelopmentofWebWorkers,whichallowtheexecutionofthescriptsinthebackgroundthatcommunicatewiththemainthreadthroughmessagepassing.Thisway,multi-threadedprogramminghasbeenbroughttothebrowser.

SomeoftheseAPIswereintroducedafterthedevelopmentofAngularJS1.xhadbegun;that’swhytheframeworkwasn’tbuildwithmostoftheminmind.However,exploitingtheAPIsgivesdevelopersmanybenefits,suchas:

Significantperformanceimprovements.Developmentofsoftwarewithbetterqualitycharacteristics.

Nowlet’sbrieflydiscusshoweachofthesetechnologieshasbeenmadepartofthenewAngularcoreandwhy.

Page 49: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 50: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TheevolutionofECMAScriptNowadays,browservendorsarereleasingnewfeaturesinshortiterations,andusersreceiveupdatesquiteoften.ThishelpsmovetheWebforwardbyallowingdeveloperstotakeadvantageofthebleeding-edgetechnologies,aimingtoimprovetheWeb.ES2015isalreadystandardized.Theimplementationofthelatestversionofthelanguagehasalreadystartedinthemajorbrowsers.Learningthenewsyntaxandtakingadvantageofitwillnotonlyincreaseourproductivityasdevelopers,butalsoprepareusforthenearfuturewhenallthebrowserswillhavefullsupportforit.Thismakesitessentialtostartusingthelatestsyntaxnow.

Someprojects’requirementsmayenforceustosupportolderbrowsers,whichdoesnotsupportanyES2015features.Inthiscase,wecandirectlywriteECMAScript5,whichhasdifferentsyntaxbutequivalentsemanticstoES2015.However,wecantakeadvantageoftheprocessoftranspilation.UsingatranspilerinourbuildprocessallowsustotakeadvantageofthenewsyntaxbywritingES2015andtranslatingittoatargetlanguagethatissupportedbythebrowsers.

AngularJShasbeenaroundsince2009.Backthen,thefrontendofmostwebsiteswaspoweredbyECMAScript3,thelastmainreleaseofECMAScriptpriortoECMAScript5.Thisautomaticallymeantthatthelanguageusedfortheframework’simplementationwasECMAScript3.TakingadvantageofthenewversionofthelanguagerequiresportingoftheentiretyofAngularJS1.xtoES2015.

Fromthebeginning,Angular2tookintoaccountthecurrentstateoftheWebbybringingthelatestsyntaxintheframework.AlthoughAngular2iswrittenwithasupersetofES2016(TypeScript,whichwe’regoingtotakealookatinamoment),itallowsdeveloperstouselanguageoftheirownpreference.WecanuseES2015or,ifweprefernottohaveanyintermediatepreprocessingofourcodeandsimplifythebuildprocess,evenECMAScript5.

Page 51: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WebComponentsThefirstpublicdraftofWebComponentswaspublishedonMay22,2012,aboutthreeyearsafterthereleaseofAngularJS1.x.Asmentioned,theWebComponentsstandardallowsustocreatecustomelementsandattachbehaviortothem.Itsoundsfamiliar;we’vealreadyusedsimilarconceptinthedevelopmentoftheuserinterfaceinAngularJS1.xapplications.WebComponentssoundlikeanalternativetoAngulardirectives;however,theyhavemoreintuitiveAPI,richerfunctionality,andbuilt-inbrowsersupport.Theyintroducedafewotherbenefitssuchasbetterencapsulation,whichisveryimportant,forexample,inhandlingCSS-stylecollisions.

ApossiblestrategyforaddingWebComponentssupportinAngularJS1.xistochangethedirectivesimplementationandintroduceprimitivesofthenewstandardintheDOMcompiler.AsAngulardevelopers,weknowhowpowerfulbutalsocomplexthedirectivesAPIis.ItincludesalotofpropertiessuchaspostLink,preLink,compile,restrict,scope,controller,andmanymore,andofcourse,ourfavoritetransclude.Approvedasstandard,WebComponentswillbeimplementedonamuchlowerlevelinthebrowsers,whichintroducesplentyofbenefitssuchasbetterperformanceandnativeAPI.

DuringtheimplementationofWebComponents,alotofwebspecialistsmetthesameproblemstheAngularteamdidwhendevelopingthedirectivesAPIandcameupwithsimilarideas.GooddesigndecisionsbehindWebComponentsincludethecontentelement,whichdealswiththeinfamoustransclusionprobleminAngularJS1.x.SinceboththedirectivesAPIandWebComponentssolvesimilarproblemsindifferentways,keepingthedirectivesAPIontopofWebComponentswouldhavebeenredundantandaddedunnecessarycomplexity.That’swhytheAngularcoreteamdecidedtostartfromthebeginningbybuildingontopofWebComponentsandtakingfulladvantageofthenewstandard.WebComponentsinvolvesnewfeatures,someofthemnotyetimplementedbyallbrowsers.Incaseourapplicationisruninabrowser,whichdoesnotsupportanyofthesefeaturesnatively,Angular2emulatesthem.Anexampleforthisisthecontentelementpolyfilledwiththedirective,ng-content.

Page 52: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WebWorkersJavaScriptisknownforitseventloop.UsuallyJavaScriptprogramsareexecutedinasinglethreadanddifferenteventsarescheduledbybeingpushedinaqueueandprocessedsequentially,intheorderoftheirarrival.However,thiscomputationalstrategyisnoteffectivewhenoneofthescheduledeventsrequiresalotofcomputationaltime.Insuchcasestheevent’shandlingisgoingtoblockthemainthreadandallothereventsarenotgoingtobehandleduntilthetimeconsumingcomputationiscompleteandpassestheexecutiontothenextoneinthequeue.Asimpleexampleofthisisamouseclickthattriggersanevent,inwhichcallbackwedosomeaudioprocessingusingtheHTML5audioAPI.Iftheprocessedaudiotrackisbigandthealgorithmrunningoveritisheavy,thiswillaffecttheuser’sexperiencebyfreezingtheUIuntiltheexecutioniscomplete.

TheWebWorkerAPIwasintroducedinordertopreventsuchpitfalls.Itallowsexecutionofheavycomputationsinsidethecontextofdifferentthread,whichleavesthemainthreadofexecutionfree,capableofhandlinguserinputandrenderingtheuserinterface.

HowcanwetakeadvantageofthisinAngular?Inordertoanswerthisquestion,let’sthinkabouthowthingsworkinAngularJS1.x.Whatifwehaveanenterpriseapplication,whichprocessesahugeamountofdatathatneedstoberenderedonthescreenusingdatabinding?Foreachbinding,anewwatcherwillbeadded.Oncethedigestloopisrun,itwillloopoverallthewatchers,executetheexpressionsassociatedwiththem,andcomparethereturnedresultswiththeresultsgainedfromthepreviousiteration.Wehaveafewslowdownshere:

Theiterationoverlargenumberofwatchers.Evaluationofexpressioningivencontext.Copyofthereturnedresult.Comparisonbetweenthecurrentresultoftheexpression’sevaluationandthepreviousone.

Allthesestepscouldbequiteslowdependingonthesizeoftheinput.Ifthedigestloopinvolvesheavycomputations,whynotmoveittoaWebWorker?WhynotrunthedigestloopinsideWebWorker,getthechangedbindings,andapplythemtotheDOM?

Therewereexperimentsbythecommunity,whichaimedforthisresult.However,theirintegrationintotheframeworkwasn’ttrivial.OneofthemainreasonsbehindthelackofsatisfyingresultswasthecouplingoftheframeworkwiththeDOM.Often,insidethewatchers’callbacks,AngulardirectlymanipulatestheDOM,whichmakesitimpossibletomovethewatchersinsideWebWorkerssincetheWebWorkersareinvokedinanisolatedcontext,withoutaccesstotheDOM.InAngularJS1.x,wemayhaveimplicitorexplicitdependenciesbetweenthedifferentwatchers,whichrequiremultipleiterationsofthedigestloopinordertogetstableresults.Combiningthelasttwopoints,itisquitehardtoachievepracticalresultsincalculatingthechangesinthreadsotherthanthemainthreadofexecution.

FixingthisinAngularJS1.xintroducesagreatdealofcomplexityintheinternalimplementation.Theframeworksimplywasnotbuiltwiththisinmind.Since

Page 53: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WebWorkerswereintroducedbeforetheAngular2designprocessstarted,thecoreteamtooktheminmindfromthebeginning.

Page 54: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 55: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

LessonslearnedfromAngularJS1.xinthewildAlthoughtheprevioussectionintroducedalotofargumentsfortherequiredreimplementationoftheframeworkrespondingtothelatesttrends,it’simportanttorememberthatwe’renotstartingcompletelyfromscratch.We’retakingwhatwe’velearnedfromAngularJS1.xwithus.Intheperiodsince2009,theWebisnottheonlythingthatevolved.Wealsostartedbuildingmoreandmorecomplexapplications.Today,single-pageapplicationsarenotsomethingexotic,butmorelikeastrictrequirementforallthewebapplicationssolvingbusinessproblems,whichareaimingforhighperformanceandgooduserexperience.

AngularJS1.xhelpedustobuildhighly-efficientandlarge-scalesingle-pageapplications.However,byapplyingitinvarioususecases,we’vealsodiscoveredsomeofitspitfalls.Learningfromthecommunity’sexperience,Angular’scoreteamworkedonnewideasaimingtoanswerthenewrequirements.AswelookatthenewfeaturesofAngular2,let’sconsidertheminthelightofthecurrentimplementationofAngularJS1.xandthinkaboutthethingswithwhichwe,asAngulardevelopers,havestruggledandwhichwehavemodifiedoverthelastfewyears.

Page 56: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ControllersAngularJS1.xfollowstheModelViewController(MVC)micro-architecturalpattern.SomemayarguethatitlooksmorelikeModelViewViewModel(MVVM)becauseoftheviewmodelattachedaspropertiestothescopeorthecurrentcontextincaseofcontrollerassyntax.ItcouldbeapproacheddifferentlyagainifweusetheModelViewPresenterpattern(MVP).BecauseofallthedifferentvariationsofhowwecanstructurethelogicinourapplicationsthecoreteamcalledAngularJS1.xaModelViewWhatever(MVW)framework.

TheviewinanyAngularJSapplicationissupposedtobeacompositionofdirectives.Thedirectivescollaboratetogetherinordertodeliverfullyfunctionaluserinterfaces.Servicesareresponsibleforencapsulatingthebusinesslogicoftheapplications.That’stheplacewhereweshouldputthecommunicationwithRESTfulservicesthroughHTTP,real-timecommunicationwithWebSocketsandevenWebRTC.Servicesarethebuildingblockwhereweshouldimplementthedomainmodelsandbusinessrulesofourapplications.There’sonemorecomponent,whichismostlyresponsibleforhandlinguserinputanddelegatingtheexecutiontotheservices—thecontroller.

Althoughtheservicesanddirectiveshavewell-definedroles,wecanoftenseetheanti-patternoftheMassiveViewController,whichiscommoniniOSapplications.Occasionally,developersaretemptedtoaccessorevenmanipulatetheDOMdirectlyfromtheircontrollers.Initially,thishappensforachievingsomethingsimple,suchaschangingthesizeofanelement,orquickanddirtychangingelements’styles.Anothernoticeableanti-patternisduplicationofbusinesslogicacrosscontrollers.Oftendeveloperstendtocopyandpastelogic,whichshouldbeencapsulatedinsideservices.

ThebestpracticesforbuildingAngularJSapplicationsstateisthatthecontrollersshouldnotmanipulatetheDOMatall,insteadallDOMaccessandmanipulationsshouldbeisolatedindirectives.Ifwehavesomerepetitivelogicbetweencontrollers,mostlikelywewanttoencapsulateitintoaserviceandinjectthisservicewiththedependencyinjectionmechanismofAngularJSinallthecontrollersthatneedthatfunctionality.

Thisiswherewe’recomingfrominAngularJS1.x.Allthissaid,itseemsthatthefunctionalityofcontrollerscouldbemovedintothedirective’scontrollers.SincedirectivessupportthedependencyinjectionAPI,afterreceivingtheuser’sinput,wecandirectlydelegatetheexecutiontoaspecificservice,alreadyinjected.ThisisthemainreasonAngular2usesadifferentapproachbyremovingtheabilitytoputcontrollerseverywherebyusingtheng-controllerdirective.We’lltakealookathowAngularJS1.xcontrollers’responsibilitiescouldbetakenfromAngular2componentsanddirectivesinChapter4,GettingStartedwithAngular2ComponentsandDirectives.

Page 57: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ScopeThedata-bindinginAngularJSisachievedusingthescopeobject.Wecanattachpropertiestoitandexplicitlydeclareinthetemplatethatwewanttobindtotheseproperties(oneortwo-way).Althoughtheideaofthescopeseemsclear,thescopehastwomoreresponsibilities,includingeventdispatchingandthechangedetection-relatedbehavior.Angularbeginnershaveahardtimeunderstandingwhatscopereallyisandhowitshouldbeused.AngularJS1.2introducedsomethingcalledcontrollerassyntax.Itallowsustoaddpropertiestothecurrentcontextinsidethegivencontroller(this),insteadofexplicitlyinjectingthescopeobjectandlateraddingpropertiestoit.Thissimplifiedsyntaxcanbedemonstratedfromthefollowingsnippet:

<divng-controller="MainCtrlasmain">

<buttonng-click="main.clicked()">Click</button>

</div>

functionMainCtrl(){

this.name='Foobar';

}

MainCtrl.prototype.clicked=function(){

alert('Youclickedme!');

};

Angular2tookthisevenfurtherbyremovingthescopeobject.AlltheexpressionsareevaluatedinthecontextofgivenUIcomponent.RemovingtheentirescopeAPIintroduceshighersimplicity;wedon’tneedtoexplicitlyinjectitanymoreandweaddpropertiestotheUIcomponentstowhichwecanlaterbind.ThisAPIfeelsmuchsimplerandmorenatural.

We’regoingtotakemoredetailedlookatthecomponentsandthechangedetectionmechanismofAngular2inChapter4,GettingStartedwithAngular2ComponentsandDirectives.

Page 58: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DependencyInjectionMaybethefirstframeworkonthemarketthatincludedinversionofcontrol(IoC)throughdependencyinjection(DI)intheJavaScriptworldwasAngularJS1.x.DIprovidesanumberofbenefits,suchaseasiertestability,bettercodeorganizationandmodularization,andsimplicity.AlthoughtheDIin1.xdoesanamazingjob,Angular2takesthisevenfurther.SinceAngular2isontopofthelatestwebstandards,itusestheECMAScript2016decorators’syntaxforannotatingthecodeforusingDI.DecoratorsarequitesimilartothedecoratorsinPythonorannotationsinJava.Theyallowustodecoratethebehaviorofagivenobjectbyusingreflection.Sincedecoratorsarenotyetstandardizedandsupportedbymajorbrowsers,theirusagerequiresanintermediatetranspilationstep;however,ifyoudon’twanttotakeit,youcandirectlywritealittlebitmoreverbosecodewithECMAScript5syntaxandachievethesamesemantics.

ThenewDIismuchmoreflexibleandfeature-rich.ItalsofixessomeofthepitfallsofAngularJS1.xsuchasthedifferentAPIs;in1.x,someobjectsareinjectedbyposition(suchasthescope,element,attributes,andcontrollerinthedirectives’linkfunction)andothers,byname(usingparametersnamesincontrollers,directives,services,andfilters).

WewilltakeafurtherlookattheAngular2’sdependencyinjectionAPIinChapter5,DependencyInjectioninAngular2.

Page 59: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Server-siderenderingThebiggertherequirementsoftheWebare,themorecomplexthewebapplicationsbecome.Buildingareal-life,single-pageapplicationrequireswritingahugeamountofJavaScript,andincludingalltherequiredexternallibrariesmayincreasethesizeofthescriptsonourpagetoafewmegabytes.Theinitializationoftheapplicationmaytakeuptoseveralsecondsoreventensofsecondsonmobileuntilalltheresourcesgetfetchedfromtheserver,theJavaScriptisparsedandexecuted,thepagegetsrendered,andallthestylesareapplied.Onlow-endmobiledevicesthatuseamobileInternetconnection,thisprocessmaymaketheusersgiveuponvisitingourapplication.Althoughthereareafewpracticesthatspeedupthisprocess,incomplexapplications,there’snosilverbullet.

Intheprocessoftryingtoimprovetheuserexperience,developersdiscoveredsomethingcalledserver-siderendering.Itallowsustorendertherequestedviewofasingle-pageapplicationontheserveranddirectlyprovidetheHTMLforthepagetotheuser.Later,oncealltheresourcesareprocessed,theeventlistenersandbindingscanbeaddedbythescriptfiles.Thissoundslikeagoodwaytoboosttheperformanceofourapplication.OneofthepioneersinthiswasReactJS,whichallowedpre-renderingoftheuserinterfaceontheserversideusingNode.jsDOMimplementations.Unfortunately,thearchitectureofAngularJS1.xdoesnotallowthis.TheshowstopperisthestrongcouplingbetweentheframeworkandthebrowserAPIs,thesameissuewehadinrunningthechangedetectioninWebWorkers.

Anothertypicalusecasefortheserver-siderenderingisforbuildingSearchEngineOptimization(SEO)-friendlyapplications.TherewereacoupleofhacksusedinthepastformakingtheAngularJS1.xapplicationsindexablebythesearchengines.Onesuchpractice,forinstance,istraversaloftheapplicationwithaheadlessbrowser,whichexecutesthescriptsoneachpageandcachestherenderedoutputintoHTMLfiles,makingitaccessiblebythesearchengines.

AlthoughthisworkaroundforbuildingSEO-friendlyapplicationsworks,server-siderenderingsolvesbothofthementionedissues,improvingtheuserexperienceandallowingustobuildSEO-friendlyapplicationsmuchmoreeasilyandfarmoreelegantly.

ThedecouplingofAngular2withtheDOMallowsustorunourAngular2applicationsoutsidethecontextofthebrowser.Thecommunitytookadvantageofthisbybuildingatool,allowingustoprerendertheviewsofoursingle-pageapplicationontheserversideandforwardthemtothebrowser.Atthetimeofwritingthefollowingcontent,thetoolisstillintheearlyphasesofitsdevelopmentandisoutsidetheframework’score.We’regoingtotakeafurtherlookatitinChapter8,DevelopmentExperienceandServer-SideRendering.

Page 60: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ApplicationsthatscaleMVWhasbeenthedefaultchoiceforbuildingsingle-pageapplicationssinceBackbone.jsappeared.Itallowsseparationofconcernsbyisolatingthebusinesslogicfromtheview,allowingustobuildwell-designedapplications.Exploitingtheobserverpattern,MVWallowslisteningformodelchangesintheviewandupdatingitwhenchangesaredetected.However,therearesomeexplicitandimplicitdependenciesbetweentheseeventhandlers,whichmakethedataflowinourapplicationsnotobviousandhardtoreasonabout.InAngularJS1.x,weareallowedtohavedependenciesbetweenthedifferentwatchers,whichrequiresthedigestlooptoiterateoverallofthemacoupleoftimesuntiltheexpressions’resultsgetstable.Angular2makesthedata-flowone-directional,whichhasanumberofbenefits,including:

Moreexplicitdata-flow.Nodependenciesbetweenbindings,sonotimetolive(TTL)ofthedigest.Betterperformance:

Thedigestloopisrunonlyonce.Wecancreateapps,whicharefriendlytoimmutable/observablemodels,thatallowsustomakefurtheroptimizations.

Thechangeinthedata-flowintroducesonemorefundamentalchangeinAngularJS1.xarchitecture.

WemaytakeanotherperspectiveonthisproblemwhenweneedtomaintainalargecodebasewritteninJavaScript.AlthoughJavaScript’sducktypingmakesthelanguagequiteflexible,italsomakesitsanalysisandsupportbyIDEsandtexteditorsharder.Refactoringoflargeprojectsgetsveryhardanderror-pronebecauseinmostcases,thestaticanalysisandtypeinferenceareimpossible.Thelackofcompilermakestyposalltooeasy,whicharehardtonoticeuntilwerunourtestsuiteorruntheapplication.

Page 61: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TheAngularcoreteamdecidedtouseTypeScriptbecauseofthebettertoolingpossiblewithitandthecompile-timetypechecking,whichhelpusbemoreproductiveandlesserror-prone.Astheprecedingfigureshows,TypeScriptisasupersetofECMAScript;itintroducesexplicittypeannotationsandacompiler.TheTypeScriptlanguageiscompiledtoplainJavaScript,supportedbytoday’sbrowsers.Sinceversion1.6,TypeScriptimplementstheECMAScript2016decorators,whichmakesittheperfectchoiceforAngular2.

TheusageofTypeScriptallowsmuchbetterIDEandtexteditorssupportwithstaticcodeanalysisandtypechecking.Allthisincreasesourproductivitydramaticallybyreducingthemistakeswemakeandsimplifyingtherefactoringprocess.AnotherimportantbenefitofTypeScriptistheperformanceimprovementweimplicitlygetbythestatictyping,whichallowsrun-timeoptimizationsbytheJavaScriptvirtualmachine.

We’llbetalkingaboutTypeScriptindetailinChapter3,TypeScriptCrashCourse.

Page 62: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TemplatesTemplatesareoneofthekeyfeaturesinAngularJS1.x.TheyaresimpleHTMLanddonotrequireanyintermediateprocessingandcompilation,unlikemosttemplateenginessuchasmustache.TemplatesinAngularJScombinesimplicitywithpowerbyallowingustoextendHTMLbycreatinganinternalDomainSpecificLanguage(DSL)insideit,withcustomelementsandattributes.

However,thisisoneofthemainpurposesbehindwebcomponentsaswell.WealreadymentionedhowandwhyAngular2takesadvantageofthisnewtechnology.AlthoughAngularJS1.xtemplatesaregreat,theycanstillgetbetter!Angular2templatestookthebestpartsoftheonesinthepreviousreleaseoftheframeworkandenhancedthembyfixingsomeoftheirconfusingparts.

Forexample,let’ssaywebuiltadirectiveandwewanttoallowtheusertopassapropertytoitbyusinganattribute.InAngularJS1.x,wecanapproachthisinthreedifferentways:

<username="literal"></user>

<username="expression"></user>

<username="{{interpolate}}"></user>

Ifwehaveadirectiveuserandwewanttopassthenameproperty,wecanapproachinthreedifferentways.Wecaneitherpassaliteral(inthiscase,thestring"literal"),astring,whichwillbeevaluatedasanexpression(inourcase"expression"),oranexpressioninside{{}}.Whichsyntaxshouldbeusedcompletelydependsonthedirective’simplementation,whichmakesitsAPI-tangledandhardtoremember.

Itisafrustratingtasktodealwithlargeamountofcomponentswithdifferentdesigndecisionsonadailybasis.Byintroducingacommonconvention,wecandealwithsuchproblems.However,inordertohavegoodresultsandconsistentAPIs,theentirecommunityneedstoagreewithit.

Angular2dealswiththisproblemaswellbyprovidingspecialsyntaxforattributes,whosevaluesneedtobeevaluatedinthecontextofthecurrentcomponent,andadifferentsyntaxforpassingliterals.

Anotherthingwe’reusedto,basedonourAngularJS1.xexperience,isthemicrosyntaxusedintemplatedirectivessuchasng-if,ng-for.Forinstance,ifwewanttoiterateoveralistofusersanddisplaytheirnamesinAngularJS1.x,wecanuse:

<divng-for="userinusers">{{user.name}}</div>

Althoughthissyntaxlooksintuitivetous,itallowslimitedtoolingsupport.However,Angular2approachedthisdifferentlybybringingalittlebitmoreexplicitsyntaxwithrichersemantics:

<templatengForvar-user[ngForOf]="users">

{{user.name}}

</template>

Theprecedingsnippetexplicitlydefinestheproperty,whichhastobecreatedinthe

Page 63: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

contextofthecurrentiteration(user),theoneweiterateover(users).

However,thissyntaxistooverbosefortyping.Developerscanusethefollowingsyntax,whichlatergetstranslatedtothemoreverboseone:

<li*ngFor="#userofusers">

{{user.name}}

</li>

TheimprovementsinthenewtemplateswillalsoallowbettertoolingforadvancedsupportbytexteditorsandIDEs.We’regoingtodiscussAngular2’stemplatesinChapter4,GettingStartedwithAngular2ComponentsandDirectives.

Page 64: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ChangedetectionIntheWebWorkerssection,wealreadymentionedtheopportunitytorunthedigestloopinthecontextofadifferentthread,instantiatedasWebWorker.However,theimplementationofthedigestloopinAngularJS1.xisnotquitememory-efficientandpreventstheJavaScriptvirtualmachinefromdoingfurthercodeoptimizations,whichallowssignificantperformanceimprovements.Onesuchoptimizationistheinlinecaching(http://mrale.ph/blog/2012/06/03/explaining-js-vms-in-js-inline-caches.html).TheAngularteamdidalotofresearchdiscoveringdifferentwaystheperformanceandtheefficiencyofthedigestloopcouldbeimproved.Thisledtothedevelopmentofabrandnewchangedetectionmechanism.

Inordertoallowfurtherflexibility,theAngularteamabstractedthechangedetectionanddecoupleditsimplementationfromtheframework’score.Thisallowedthedevelopmentofdifferentchangedetectionstrategies,empoweringdifferentfeaturesindifferentenvironments.

Asaresult,Angular2hastwobuilt-inchangedetectionmechanisms:

Dynamicchangedetection:ThisissimilartothechangedetectionmechanismusedbyAngularJS1.x.Itisusedinsystemswithdisallowedeval(),suchasCSPandChromeextensions.JITchangedetection:Thisgeneratesthecodethatperformsthechangedetectionrun-time,allowingtheJavaScriptvirtualmachinetoperformfurthercodeoptimizations.

We’regoingtotakealookatthenewchangedetectionmechanismsandhowwecanconfiguretheminChapter4,GettingStartedwithAngular2ComponentsandDirectives.

Page 65: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 66: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SummaryInthischapter,weconsideredthemainreasonsbehindthedecisionstakenbytheAngularcoreteamandthelackofbackwardcompatibilitybetweenthelasttwomajorversionsoftheframework.Wesawthatthesedecisionswerefueledbytwothings—theevolutionoftheWebandtheevolutionofthefrontenddevelopment,withthelessonslearnedfromthedevelopmentofAngularJS1.xapplications.

Inthefirstsection,welearnedwhyweneedtousethelatestversionoftheJavaScriptlanguage,whywewanttotakeadvantageofWebComponentsandWebWorkers,andwhyit’snotworthittointegrateallthesepowerfultoolsinversion1.x.

Weobservedthecurrentdirectionoffrontenddevelopmentandthelessonslearnedinthelastfewyears.WedescribedwhythecontrollerandscopewereremovedfromAngular2,andwhyAngularJS1.x’sarchitecturewaschangedinordertoallowserver-siderenderingforSEO-friendly,high-performance,single-pageapplications.Anotherfundamentaltopicwetookalookatwasbuildinglarge-scaleapplications,andhowthatmotivatedsingle-waydata-flowintheframeworkandthechoiceofthestatically-typedlanguageTypeScript.

Inthenextchapter,we’regoingtolookatthemainbuildingblocksofanAngular2application—howtheycanbeusedandhowtheyrelatetoeachother.Angular2reusessomeofthenamingofthecomponentsintroducedbyAngularJS1.x,butgenerallychangesthebuildingblocksofoursingle-pageapplicationscompletely.We’regoingtopeekatthenewcomponents,andcomparethemwiththeonesinthepreviousversionoftheframework.We’llmakeaquickintroductiontodirectives,components,routers,pipes,andservices,anddescribehowtheycouldbecombinedforbuildingclassy,single-pageapplications.

TipDownloadingtheexamplecode

Youcandownloadtheexamplecodefilesforthisbookfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.

Youcandownloadthecodefilesbyfollowingthesesteps:

Loginorregistertoourwebsiteusingyoure-mailaddressandpassword.HoverthemousepointerontheSUPPORTtabatthetop.ClickonCodeDownloads&Errata.EnterthenameofthebookintheSearchbox.Selectthebookforwhichyou’relookingtodownloadthecodefiles.Choosefromthedrop-downmenuwhereyoupurchasedthisbookfrom.ClickonCodeDownload.

Oncethefileisdownloaded,pleasemakesurethatyouunziporextractthefolderusingthelatestversionof:

Page 67: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WinRAR/7-ZipforWindowsZipeg/iZip/UnRarXforMac7-Zip/PeaZipforLinux

Page 68: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 69: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Chapter2.TheBuildingBlocksofanAngular2ApplicationInthepreviouschapter,welookedatthedriversforthedesigndecisionsbehindAngular2.Wedescribedthemainreasonsthatledtothedevelopmentofabrandnewframework;Angular2takesadvantageofwebstandardswhilekeepingthepastlessonsinmind.Althoughwearefamiliarwiththemaindrivers,westillhaven’tdescribedthecoreAngular2concepts.ThelastmajorreleaseoftheframeworktookadifferentpathfromAngularJS1.xandintroducedalotofchangesinthefundamentalbuildingblocksusedforthedevelopmentofsingle-pageapplications.

Inthischapter,we’lllookattheframework’scoreandmakeabriefintroductiontothemaincomponentsofAngular2.Anotherimportantpurposeofthischapteristotakeanoverviewofhowtheseconceptscanbeputtogethertohelpusbuildprofessionaluserinterfacesforourwebapplications.Thefollowingsectionswillgiveusanoverviewofeverythingthatwearegoingtotakealookatinmoredetaillaterinthebook.

Inthischapter,we’regoingtolookat:

Aconceptualoverviewoftheframework,showinghowdifferentconceptsrelatetoeachother.Howwecanbuildauserinterfaceasacompositionofcomponents.WhatpaththedirectivestookinAngular2,andhowtheirinterfacechangedcomparedtothepreviousmajorversionoftheframework.Thereasonsfortheenforcedseparationofconcerns,whichledtothedecompositionofthedirectivesintotwodifferentcomponents.Inordertogetbettersenseofthesetwoconcepts,we’regoingtodemonstratebasicsyntaxfortheirdefinition.Anoverviewoftheimprovedchangedetection,andhowitinvolvesthecontextthatdirectivesprovide.Whatzonesare,andwhytheycanmakeourdailydevelopmentprocesseasier.Whatpipesare,andhowaretheyrelatedtotheAngularJS1.xfilters.Thebrand-newdependencyinjection(DI)mechanisminAngular2andhowitisrelatedtotheservicecomponent.

Page 70: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

AconceptualoverviewofAngular2BeforewediveintodifferentpartsofAngular2,let’sgetaconceptualoverviewofhoweverythingfitstogether.Let’shavealookatthefollowingdiagram:

Fig.1

Fig.1toFig.4showsthemainAngular2conceptsandtheconnectionsbetweenthem.Themainpurposeofthesediagramsistoillustratethecoreblocksforbuildingsingle-pageapplicationswithAngular2,andtheirrelations.

TheComponentisthemainbuildingblockwe’regoingtousetocreatetheuserinterfaceofourapplicationswithAngular2.TheComponentisadirectsuccessoroftheDirective,whichistheprimitiveforattachingbehaviortotheDOM.ComponentsextendDirectivesbyprovidingfurtherfeatures,suchasaviewwithanattachedtemplate,whichcanbeusedforrenderingcompositionofdirectives.Insidethetemplateoftheviewcanresidedifferentexpressions.

Page 71: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Fig.2

TheprecedingdiagramillustratesconceptuallytheChangeDetectionmechanismofAngular2.Itrunsthedigestloop,whichevaluatestheregisteredexpressionsinthecontextofspecificUIcomponents.SincetheconceptofscopehasbeenremovedfromAngular2,theexecutioncontextoftheexpressionsarethecontrollersofthecomponentsassociatedwiththem.

TheChangeDetectionmechanismcanbeenhancedusingDiffers;that’swhythere’sadirectrelationbetweenthesetwoelementsonthediagram.

PipesareanothercomponentofAngular2.WecanthinkofthePipesasthefiltersfromAngularJS1.x.Pipescanbeusedtogetherwithcomponents.Wecanincludethemintheexpressions,whicharedefinedinthecontextofanycomponent:

Fig.3

Page 72: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Nowlet’stakealookattheprecedingdiagram.DirectivesandComponentsdelegatethebusinesslogictoServices.Thisenforcesbetterseparationofconcerns,maintainability,andreusabilityofcode.DirectivesreceivereferencestoinstancesofspecificservicesdeclaredasdependenciesusingtheDImechanismoftheframework,anddelegatetheexecutionofthebusinessrelatedlogictothem.BothDirectivesandComponentsmayusetheDImechanism,notonlytoinjectservices,butalsotoinjectDOMelementsand/orotherComponentsorDirectives.

Fig.4

Lastly,thecomponent-basedrouterisusedfordefiningtheroutesinourapplication.SinceDirectivesdonotownatemplate,onlytheComponentscanberenderedbytherouter,representingthedifferentviewsinourapplication.Therouteralsousesthepredefineddirectives,whichallowustodefinehyperlinksbetweenthedifferentviewsandthecontainerwheretheyshouldberendered.

Nowwe’regoingtolookmorecloselyattheseconcepts,seehowtheyworktogethertomakeAngular2applications,andhowthey’vechangedfromtheirAngularJS1.xpredecessors.

Page 73: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 74: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ChangingdirectivesAngularJS1.xintroducedtheconceptofdirectivesinthedevelopmentofsingle-pageapplications.ThepurposeofdirectivesistoencapsulatetheDOM-relatedlogic,andallowustobuilduserinterfacesascompositionsofsuchcomponentsbyextendingthesyntaxandthesemanticsofHTML.Initially,likemostinnovativeconcepts,directiveswereviewedcontroversiallybecausetheypredisposeustowriteinvalidHTMLwhenusingcustomelementsorattributeswithoutthedata-prefix.However,overtime,thisconcepthasgraduallybeenaccepted,andhasprovedthatitisheretostay.

AnotherdrawbackoftheimplementationofdirectivesinAngularJS1.xarethedifferentwayswecanusethem.Thisrequiresunderstandingoftheattributevalues,whichcanbeliterals,expressions,callbacks,ormicrosyntax.Thismakestoolingessentiallyimpossible.

Angular2keepstheconceptofdirectives,buttakesthebestpartsfromAngularJS1.xandaddssomenewideasandsyntax.ThemainpurposeofAngular2’sdirectivesistoattachbehaviortotheDOMbyextendingitwithcustomlogicdefinedinanES2015class.Wecanthinkoftheseclassesascontrollersassociatedtothedirectives,andthinkoftheirconstructorsassimilartothelinkingfunctionofthedirectivesfromAngularJS1.x.However,thenewdirectiveshavelimitedconfigurability.Theydonotallowforthedefinitionofatemplate,whichmakesmostofthealreadyknownpropertiesfordefiningdirectivesunnecessary.ThesimplicityofthedirectivesAPIdoesnotlimittheirbehavior,butonlyenforcesstrongerseparationofconcerns.TocomplementthismoresimpledirectiveAPI,Angular2hasintroducedaricherinterfaceforthedefinitionofUIelements,calledcomponents.Componentsextendthefunctionalityofdirectivesbyallowingthemtoownatemplate,throughtheComponentmetadata.We’regoingtotakeafurtherlookatcomponentslater.

ThesyntaxusedforAngular2directivesinvolvesES2016decorators.However,wecanalsouseTypeScript,ES2015,orevenECMAScript5(ES5)inordertoachievethesameresultwithalittlebitmoretyping.Thefollowingcodedefinesasimpledirective,writteninTypeScript:

@Directive({

selector:'[tooltip]'

})

exportclassTooltip{

privateoverlay:Overlay;

@Input()

privatetooltip:string;

constructor(privateel:ElementRef,manager:OverlayManager){

this.overlay=manager.get();

}

@HostListener('mouseenter')

onMouseEnter(){

this.overlay.open(this.el.nativeElement,this.tooltip);

}

@HostListener('mouseleave')

onMouseLeave(){

Page 75: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

this.overlay.close();

}

}

Thedirectivecanbeusedwiththefollowingmarkupinourtemplate:

<divtooltip="42">Tellmetheanswer!</div>

Oncetheuserpointsoverthethelabel,Tellmetheanswer!,Angularwillinvokethemethod,definedunderthe@HostListenerdecoratorinthedirective’sdefinition.Intheend,theopenmethodoftheoverlaymanagerwillbeexecuted.Sincewecanhavemultipledirectivesonasingleelement,thebestpracticesstatethatweshoulduseanattributeasaselector.

AnalternativeECMAScript5syntaxforthedefinitionofthisdirectiveis:

varTooltip=ng.core.Directive({

selector:'[tooltip]',

inputs:['tooltip'],

host:{

'(mouseenter)':'onMouseEnter()',

'(mouseleave)':'onMouseLeave()'

}

})

.Class({

constructor:[ng.core.ElementRef,Overlay,function(tooltip,el,

manager){

this.el=el;

this.overlay=manager.get();

}],

onMouseEnter(){

this.overlay.open(this.el.nativeElement,this.tooltip);

},

onMouseLeave(){

this.overlay.close();

}

});

TheprecedingES5syntaxdemonstratestheinternalJavaScriptDomainSpecificLanguage(DSL)thatAngular2providesinordertoallowustowriteourcodewithoutthesyntax,whichisnotyetsupportedbymodernbrowsers.

WecansummarizethatAngular2haskepttheconceptofdirectivesbymaintainingtheideaofattachingbehaviortotheDOM.Thecoredifferencesbetween1.xand2arethenewsyntax,andthefurtherseparationofconcernsintroducedbybringingthecomponents.InChapter4,GettingStartedwithAngular2ComponentsandDirectives,wewilltakeafurtherlookatdirectives’API.We’llalsocomparethedirectives’definitionsyntaxusingES2016andES5.Nowlet’shavealookatthebigchangetoAngular2components.

Page 76: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 77: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

GettingtoknowAngular2componentsModelViewController(MVC)isamicro-architecturalpatterninitiallyintroducedfortheimplementationofuserinterfaces.AsAngularJSdevelopers,weusedifferentvariationsofthispatternonadailybasis,mostoftenModelViewViewModel(MVVM).InMVC,wehavethemodel,whichencapsulatesthebusinesslogicofourapplication,andtheview,whichisresponsibleforrenderingtheuserinterface,acceptinguserinput,aswellasdelegatingtheuserinteractionlogictothecontroller.Theviewisrepresentedasthecompositionofcomponents,whichisformallyknownasthecompositedesignpattern.

Let’stakealookatthefollowingstructuraldiagram,whichshowsthecompositedesignpattern:

Fig.5

Herewehavethreeclasses:

AnabstractclasscalledComponent.TwoconcreteclassescalledLeafandComposite.TheLeafclassisasimpleterminalcomponentinthecomponenttreethatwe’regoingtobuildsoon.

TheComponentclassdefinesanabstractoperationcalledoperation.BothLeafandCompositeinheritfromtheComponentclass.However,theCompositeclassalsoownsreferencestoit.WecantakethisevenfurtherandallowCompositetoownalistofreferencestoComponentinstances,asshowninthediagram.ThecomponentslistinsideCompositecanholdreferencestodifferentCompositeorLeafinstances,orinstancesofotherclasses,whichextendtheComponentclassoranyofitssuccessors.Intheimplementationofthemethod,operation,insideComposite,theinvokedoperationofthedifferentinstancesinsidetheloopcanbehavedifferently.Thisisbecauseofthelatebindingmechanismusedfortheimplementationofthepolymorphisminobject-orientedprogramminglanguages.

Page 78: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ComponentsinactionEnoughoftheory!Let’sbuildacomponenttreebasedontheclasshierarchyillustratedinthediagram.Thisway,we’regoingtodemonstratehowwecantakeadvantageofthecompositepatternforbuilding,userinterfacebyusingsimplifiedsyntax.We’regoingtotakealookatasimilarexampleinthecontextofAngular2inChapter4,GettingStartedwithAngular2ComponentsandDirectives:

Compositec1=newComposite();

Compositec2=newComposite();

Compositec3=newComposite();

c1.components.push(c2);

c1.components.push(c3);

Leafl1=newLeaf();

Leafl2=newLeaf();

Leafl3=newLeaf();

c2.components.push(l1);

c2.components.push(l2);

c3.components.push(l3);

Theprecedingpseudo-codecreatesthreeinstancesoftheCompositeclassandthreeinstancesoftheLeafclass.Theinstance,c1,holdsreferencestoc2andc3insidethecomponentslist.Theinstance,c2,holdsreferencestol1andl2,andc3holdsreferencetol3:

Page 79: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Fig.6

Theprecedingdiagramisagraphicalrepresentationofthecomponenttreewebuiltinthesnippet.ThisisaquitesimplifiedversionofwhattheviewinthemodernJavaScriptframeworkslookssimilarto.However,itillustratestheverybasicsofhowwecancomposedirectivesandcomponents.Forinstance,inthecontextofAngular2wecanthinkofdirectivesasinstancesoftheprecedingLeafclass(sincetheydon’townviewandthuscannotcomposeotherdirectivesandcomponents),andcomponentsasinstancesoftheCompositeclass.

IfwethinkmoreabstractlyfortheuserinterfaceinAngularJS1.x,wecannoticethatweusequiteasimilarapproach.Thetemplatesofourviewsarecomposingdifferentdirectivestogetherinordertodeliverfullyafunctionaluserinterfacetotheenduserofourapplication.

Page 80: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ComponentsinAngular2Angular2tookthisapproachbyintroducingnewbuildingblockscalledcomponents.Componentsextendthedirectiveconceptwedescribedintheprevioussection,andprovidebroaderfunctionality.Hereisthedefinitionofabasichello-worldcomponent:

@Component({

selector:'hello-world',

template:'<h1>Hello,{{this.target}}!</h1>'

})

classHelloWorld{

target:string;

constructor(){

this.target='world';

}

}

Wecanuseitbyinsertingthefollowingmarkupinourview:

<hello-world></hello-world>

Accordingtothebestpractices,weshoulduseanelementasaselectorforourcomponentssincewemayhaveonlyasinglecomponentperDOMelement.

ThealternativeES5syntaxusingtheDSLAngularprovidesis:

varHelloWorld=ng.core.

Component({

selector:'hello-world',

template:'<h1>Hello,{{target}}!</h1>'

})

.Class({

constructor:function(){

this.target='world';

}

});

Wewilltakealookattheprecedingsyntaxinmoredetaillaterinthebook.However,let’sbrieflydescribethefunctionality,whichthiscomponentprovides.OncetheAngular2applicationhasbeenbootstrapped,itwilllookatalltheelementsofourDOMtreeandprocessthem.Onceitfindstheelementcalledhello-world,itwillinvokethelogicassociatedwithitsdefinition,whichmeansthatthetemplateofthecomponentwillberenderedandtheexpressionbetweenthecurlybracketswillbeevaluated.Thiswillresulttothemarkup,<h1>Hello,world!</h1>.

Sotosummarize,theAngularcoreteamseparatedoutthedirectivesfromAngularJS1.xintotwodifferentparts—ComponentsandDirectives.DirectivesprovideaneasywaytoattachbehaviortoDOMelementswithoutdefiningaview.ComponentsinAngular2provideapowerful,andyetsimple-to-learnAPI,whichmakesiteasiertodefinetheuserinterfaceofourapplications.Angular2ComponentsallowustodothesameamazingthingsasAngularJS1.xdirectives,butwithlesstypingandfewerthingstolearn.ComponentsextendtheAngular2directiveconceptbyaddingaviewtoit.Wecanthink

Page 81: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

oftherelationbetweenAngular2componentsanddirectivesthesamewayastherelationbetweenCompositeandLeaffromthediagramwesawinFig.5.

IfwestartillustratingtheconceptualmodelofthebuildingblocksAngular2provides,wecanpresenttherelationbetweenDirectiveandComponentasinheritance.Chapter4,GettingStartedwithAngular2ComponentsandDirectivesdescribesthesetwoconceptsinfurtherdetails.

Page 82: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 83: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

PipesInbusinessapplications,weoftenneedtohavedifferentvisualrepresentationsofthesamepieceofdata.Forexample,ifwehavethenumber100,000andwewanttoformatitascurrency,mostlikelywewon’twanttodisplayitasplaindata;morelikely,we’llwantsomethinglike$100,000.

TheresponsibilityforformattingdatainAngularJS1.xwasassignedtofilters.Anotherexampleforadataformattingrequirementiswhenweusecollectionsofitems.Forinstance,ifwehavealistofitems,wemaywanttofilteritbasedonapredicate(abooleanfunction);inalistofnumbers,wemaywanttodisplayonlyprimenumbers.AngularJS1.xhasafiltercalledfilter,whichallowsustodothis.However,theduplicationofthenamesoftenleadstoconfusion.That’sanotherreasonthecoreteamrenamedthefiltercomponenttopipe.

Themotivationbehindthenewnameisthesyntaxusedforpipesandfilters:

{{expression|decimal|currency}}

Intheprecedingexample,weapplythepipes,decimalandcurrency,tothevaluereturnedbyexpression.TheentireexpressionbetweenthecurlybraceslookslikeUnixpipesyntax.

Page 84: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningpipesThesyntaxfordefiningpipesissimilartotheoneusedforthedefinitionofdirectivesandcomponents.Inordertocreateanewpipe,wecanusetheES2015decorator,@Pipe.Itallowsustoaddmetadatatoaclass,declaringitasapipe.Allweneedtodoistoprovideanameforthepipeanddefinethedataformattinglogic.There’salsoanalternativeES5syntax,whichcanbeusedifwewanttoskiptheprocessoftranspilation.

Duringruntime,oncetheAngular2expressioninterpreterfindsoutthatagivenexpressionincludesacallofapipe,itwillretrieveitoutofthepipescollectionallocatedwithinthecomponentandinvokeitwiththeappropriatearguments.

Thefollowingexampleillustrateshowwecandefineasimplepipecalledlowercase1,whichtransformsthegivenstring,passedasargumenttoitslowercaserepresentation:

@Pipe({name:'lowercase1'})

classLowerCasePipe1implementsPipeTransform{

transform(value:string):string{

if(!value)returnvalue;

if(typeofvalue!=='string'){

thrownewError('Invalidpipevalue',value);

}

returnvalue.toLowerCase();

}

}

Inordertobeconsistent,let’sshowtheECMAScript5syntaxfordefiningpipes:

varLowercasePipe1=ng.core.

Pipe({

name:'lowercase'

})

.Class({

constructor:function(){},

transform:function(value){

if(!value)returnvalue;

if(typeofvalue==='string'){

thrownewError('Invalidpipevalue',value);

}

returnvalue.toLowerCase();

}

});

IntheTypeScriptsyntax,weimplementthePipeTransforminterfaceanddefinethetransformmethoddeclaredinsideit.However,inECMAScript5,wedonothavesupportforinterfaces,butwestillneedtoimplementthetransformmethodinordertodefineavalidAngular2pipe.WearegoingtoexplaintheTypeScriptinterfacesinthenextchapter.

Nowlet’sdemonstratehowwecanusethelowercase1pipeinsideacomponent:

@Component({

selector:'app',

pipes:[LowercasePipe1],

Page 85: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

template:'<h1>{{"SAMPLE"|lowercase1}}</h1>'

})

classApp{}

And,thealternativeECMAScript5syntaxforthisis:

varApp=ng.core.Component({

selector:'app',

pipes:[LowercasePipe1],

template:'<h1>{{"SAMPLE"|lowercase1}}</h1>'

})

.Class({

constructor:function(){}

});

WecanusetheAppcomponentwiththefollowingmarkup:

<app></app>

Theresultwearegoingtoseeonthescreenisthetextsamplewithinanh1element.

Bykeepingthedataformattinglogicasaseparatecomponent,Angular2keepsthestrongseparationofconcernsthatcanbeseenthroughout.WewilltakealookathowwecandefinestatefulandstatelesspipesforourapplicationinChapter7,Buildingareal-lifeapplicationwhileexploringpipesandhttp.

Page 86: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 87: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ChangedetectionAswesawearlier,theviewinMVCupdatesitself,basedonchangeeventsitreceivesfromthemodel.AnumberofModelViewWhatever(MVW)frameworkstookthisapproach,andembeddedtheobserverpatterninthecoreoftheirchangedetectionmechanism.

Page 88: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ClassicalchangedetectionLet’stakealookatasimpleexample,whichdoesn’tuseanyframework.SupposewehaveamodelcalledUser,whichhasapropertycalledname:

classUserextendsEventEmitter{

privatename:string;

setName(name:string){

this.name=name;

this.emit('change');

}

getName():string{

returnthis.name;}

}

TheprecedingsnippetusesTypeScript.Donotworryifthesyntaxdoesnotlookfamiliartoyou,we’regoingtomakeanintroductiontothelanguageinthenextchapter.

Theuserclassextendstheclass,EventEmitter.Thisprovidesprimitivesforemittingandsubscribingtoevents.

Nowlet’sdefineaview,whichdisplaysthenameofaninstanceoftheUserclass,passedasanargumenttoitsconstructor:

classView{

constructor(user:User,el:Element/*aDOMelement*/){

el.innerHTML=user.getName();

}

}

Wecaninitializetheviewelementby:

letuser=newUser();

user.setName('foo');

letview=newView(user,document.getElementById('label'));

Astheendresult,theuserwillseealabelwiththecontent,foo.However,changesinuserwillnotbereflectedbytheview.Inordertoupdatetheviewwhenthenameoftheuserchanges,weneedtosubscribetothechangeeventandthenupdatethecontentoftheDOMelement.WeneedtoupdatetheViewdefinitioninthefollowingway:

classView{

constructor(user:User,el:any/*aDOMelement*/){

el.innerHTML=user.getName();

user.on('change',()=>{

el.innerHTML=user.getName();

});

}

}

ThisishowmostframeworksusedtoimplementtheirchangedetectionbeforetheeraofAngularJS1.x.

Page 89: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

AngularJS1.xchangedetectionMostbeginnersarefascinatedbythedata-bindingmechanisminAngularJS1.x.ThebasicHelloWorldexamplelookssimilartothis:

functionMainCtrl($scope){

$scope.label='Helloworld!';

}

<bodyng-appng-controller="MainCtrl">

{{label}}

</body>

Ifyourunthis,Helloworld!magicallyappearsontothescreen.However,thatisnoteventhemostimpressivething!Ifweaddatextinputandwebindittothelabelpropertyofthescope,eachchangewillreflectthecontentdisplayedbytheinterpolationdirective:

<bodyng-controller="MainCtrl">

<inputng-model="label">

{{label}}

</body>

Howawesomeisthat!ThisisoneofthemainsellingpointsofAngularJS1.x—theextremeeaseofachievingdata-binding.Weaddtwo(fourifwecountng-controllerandng-app)attributesinourmarkup,addpropertytoamysticalobjectcalled$scope,whichismagicallypassedtoacustomfunctionwedefine,andeverythingsimplyworks!

However,themoreexperiencedAngulardeveloperhasabetterunderstandingofwhatisactuallygoingonbehindthescene.Intheprecedingexample,insidethedirectives,ng-modelandng-bind(inourcase,theinterpolationdirective,{{}}),Angularaddswatcherswithdifferentbehaviorassociatedtothesameexpression—label.ThesewatchersarequitesimilartotheobserversintheclassicalMVCpattern.Onsomespecificevents(inourcase,changeofthecontentofthetextinput),AngularJSwillloopoverallsuchwatchers,evaluatetheexpressionsassociatedtotheminthecontextofagivenscope,andstoretheirresults.Thisloopisknownasthedigestloop.

Intheprecedingexamples,theevaluationoftheexpression,label,inthecontextofthescopewillreturnthetext,Helloworld!.Oneachiteration,AngularJSwillcomparethecurrentresultoftheevaluationwiththepreviousresult,andwillinvoketheassociatedcallbackincasethevaluesdiffer.Forinstance,thecallbackaddedbytheinterpolationdirectivewillsetthecontentoftheelementtobethenewresultoftheexpression’sevaluation.Thisisanexampleofthedependencybetweenthecallbacksofthewatchersoftwodirectives.Thecallbackofthewatcheraddedbyng-modelmodifiestheresultoftheexpressionassociatedtothewatcheraddedbytheinterpolationdirective.

However,thisapproachhasitsowndrawbacks.Wesaidthatthedigestloopwillbeinvokedonsomespecificevents,butwhatiftheseeventshappenoutsidetheframework,forexample?WhatifweusesetTimeoutandinsidethecallback,passedasthefirstargument,wechangepropertiesattachedtothescopethatwe’rewatching?AngularJSwillbeunawareofthechangeandwon’tinvokethedigestloop,soweneedtodothat

Page 90: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

explicitlyusing$scope.$apply.Butwhatiftheframeworkknewaboutalltheasynchronouseventshappeninginthebrowser,suchasuserevents,XMLHttpRequestevents,WebSocketsrelatedevents,andothers?Insuchacase,AngularJSwouldbeabletointercepttheevent’shandlingandcouldinvokethedigestloopwithoutforcingustodoso!

Inthezone.jsThat’sexactlythecaseinAngular2.Thisfunctionalityisimplementedwithzonesusingzone.js.

Atng-confin2014,BrianFordgaveatalkaboutzones.Brianpresentedzonesasmeta-monkeypatchingofbrowserAPIs.RecentlyMiškoHeveryproposedtoTC39morematurezonesAPIforstandardization.Zone.jsisalibrarydevelopedbytheAngularteam,whichimplementszonesinJavaScript.Theyrepresentanexecutioncontext,whichallowustointerceptasynchronousbrowsercalls.Basically,byusingzones,weareabletoinvokeapieceoflogicjustafterthegivenXMLHttpRequestcompletesorwhenwereceiveanewWebSocketevent.Angular2tookadvantageofzone.jsbyinterceptingasynchronousbrowsereventsandinvokingthedigestloopjustattherighttime.ThistotallyeliminatestheneedofexplicitcallsofthedigestloopbythedeveloperusingAngular.

SimplifieddataflowThecross-watcherdependenciesmaycreateatangleddataflowinourapplication,whichishardtofollow.Thismayleadtounpredictablebehaviorandbugs,whicharehardtofind.AlthoughAngular2keptthedirtycheckingasawayforachievingchangedetection,itenforcedunidirectionaldataflow.Thishappenedbydisallowingdependenciesbetweenthedifferentwatchers,whichallowsthedigestlooptoberunonlyonce.Thisstrategyincreasestheperformanceofourapplicationsdramatically,andreducesthecomplexityofthedataflow.Angular2alsomadeimprovementstomemoryefficiencyandtheperformanceofthedigestloop.FurtherdetailsonAngular2’schangedetectionandthedifferentstrategiesusedforitsimplementationcanbefoundinChapter4,GettingStartedwithAngular2ComponentsandDirectives.

Page 91: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

EnhancingAngularJS1.x’schangedetectionNowlet’stakeastepbackandagainthinkaboutthechangedetectionmechanismoftheframework.

Wesaidthatinsidethedigestloop,Angularevaluatesregisteredexpressionsandcomparestheevaluatedvalueswiththevaluesassociatedwiththesameexpressionsinthepreviousiterationoftheloop.

Themostoptimalalgorithmusedforthecomparisonmaydifferdependingonthetypeofthevaluereturnedfromtheexpression’sevaluation.Forinstance,ifwegetamutablelistofitems,weneedtoloopovertheentirecollectionandcomparetheitemsinthecollectionsonebyoneinordertoverifythatthereisachangeornot.However,ifwehaveanimmutablelist,wecanperformacheckwithaconstantcomplexity,onlybycomparingreferences.Thisisthecasebecausetheinstancesofimmutabledatastructurescannotchange.Insteadofapplyinganoperation,whichintendstomodifysuchinstances,we’llgetanewreferencewiththemodificationapplied.

InAngularJS1.x,wecanaddwatchersusingafewmethods.Twoofthemare$watch(exp,fn,deep)or$watchCollection(exp,fn).Thesemethodsgiveussomelevelofcontroloverthewaythechangedetectionwillperformtheequalitycheck.Forexample,addingawatcherbyusing$watchandpassingafalsevalueasathirdargumentwillmakeAngularJSperformareferencecheck(thatiscomparethecurrentvaluewiththepreviousoneusing===).However,ifwepassatruthy(anytruevalue),thecheckwillbedeep(thatisusingangular.equals).Thisway,dependingontheexpectedtypeofthereturnedbytheexpressionvalue,wecanaddlistenersinthemostappropriatewayinordertoallowtheframeworktoperformequalitycheckswiththemostoptimalalgorithmavailable.ThisAPIhastwolimitations:

Itdoesnotallowyoutochoosethemostappropriateequalitycheckalgorithmatruntime.Itdoesnotallowyoutoextendthechangedetectiontothird-partiesfortheirspecificdatastructures.

TheAngularcoreteamassignedthisresponsibilitytodiffers,allowingthemtoextendthechangedetectionmechanismandoptimizeit,basedonthedataweuseinourapplications.Angular2definestwobaseclasses,whichwecanextendinordertodefinecustomalgorithms:

KeyValueDiffer:Thisallowsustoperformadvanceddiffingoverkey-value-baseddatastructures.IterableDiffer:Thisallowsustoperformadvanceddiffingoverlist-likedatastructures.

Angular2allowsustotakefullcontroloverthechangedetectionmechanismbyextendingitwithcustomalgorithms,whichwasn’tpossibleinthepreviousversionoftheframework.We’lltakeafurtherlookintothechangedetectionandhowwecanconfigureitinChapter4,GettingStartedwithAngular2ComponentsandDirectives.

Page 92: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 93: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UnderstandingservicesServicesarethebuildingblocksthatAngularprovidesforthedefinitionofthebusinesslogicofourapplications.InAngularJS1.x,wehadthreedifferentwaysfordefiningservices:

//TheFactorymethod

module.factory('ServiceName',function(dep1,dep2,…){

return{

//publicAPI

};

});

//TheServicemethod

module.service('ServiceName',function(dep1,dep2,…){

//publicAPI

this.publicProp=val;

});

//TheProvidermethod

module.provider('ServiceName',function(){

return{

$get:function(dep1,dep2,…){

return{

//publicAPI

};

}

};

});

Althoughthefirsttwosyntacticalvariationsprovidesimilarfunctionality,theydifferinthewaytheregistereddirectivewillbeinstantiated.Thethirdsyntaxallowsfurtherconfigurationoftheregisteredproviderduringconfigurationtime.

HavingthreedifferentmethodsfordefiningservicesisquiteconfusingfortheAngularJS1.xbeginners.Let’sthinkforasecondwhatnecessitatedtheintroductionofthesemethodsforregisteringservices.Whycan’twesimplyuseJavaScriptconstructorfunctions,objectliterals,orES2015classesinstead,whichAngularwillnotbeawareof?WecouldencapsulateourbusinesslogicinsideacustomJavaScriptconstructorfunctionlikethis:

functionUserTransactions(id){

this.userId=id;

}

UserTransactions.prototype.makeTransaction=function(amount){

//methodlogic

};

module.controller('MainCtrl',function(){

this.submitClick=function(){

newUserTransactions(this.userId).makeTransaction(this.amount);

};

});

Page 94: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Thiscodeiscompletelyvalid.However,itdoesn’ttakeadvantageofoneofthekeyfeaturesthatAngularJS1.xprovides—theDImechanism.TheMainCtrlfunctionusestheconstructorfunction,UserTransaction,whichisvisibleinitsbody.Theprecedingcodehastwomainpitfalls:

We’recoupledwiththelogicusedfortheservice’sinstantiation.Thecodeisnottestable.InordertomockUserTransactions,weneedtomonkeypatchit.

HowdoesAngularJSdealwiththesetwothings?Whenagivenserviceisrequired,throughtheDImechanismoftheframework,AngularJSresolvesallofitsdependenciesandinstantiatesitbypassingthemtothefactoryfunction,whichencapsulatesthelogicforitscreation.Thefactoryfunctionispassedasthesecondargumenttothefactoryandservicemethods.Theprovidermethodallowsdefinitionofaserviceonlowerlevel;thefactorymethodthereistheoneunderthe$getpropertyoftheprovider.

JustlikeAngularJS1.x,Angular2toleratesthisseparationofconcernsaswell,sothecoreteamkepttheservices.IncontrasttoAngularJS1.x,thelastmajorversionoftheframeworkprovidesamuchsimplerinterfaceforthedefinitionofservicesbyallowingustouseplainES2015classesorES5constructorfunctions.Wecannotescapefromthefactthatweneedtoexplicitlystatewhichservicesshouldbeavailableforinjectionandsomehowspecifyinstructionsfortheirinstantiation.However,Angular2usestheES2016decorator’ssyntaxforthispurposeinsteadofthemethodsfamiliartousfromAngularJS1.x.ThisallowsustodefinetheservicesinourapplicationsassimpleasES2015classes,withdecoratorsforconfigurationoftheDI:

import{Inject,Injectable}from'angular2/core';

@Injectable()

classHttpService{

constructor(){/*…*/}

}

@Injectable()

classUser{

constructor(privateservice:HttpService){}

save(){

returnthis.service.post('/users')

.then(res=>{

this.id=res.id;

returnthis;

});

}

}

ThealternativeECMAScript5syntaxis:

varHttpService=ng.core.Class({

constructor:function(){}

});

varUser=ng.core.Class({

constructor:[HttpService,function(service){

Page 95: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

this.service=service;

}],

save:function(){

returnthis.service.post('/users')

.then(function(res){

this.id=res.id;

returnthis;

});

}

});

Servicesarerelatedtothecomponentsandthedirectivesdescribedintheprevioussections.FordevelopinghighlycoherentandreusableUIcomponents,weneedtomoveallthebusiness-relatedlogictoinsideourservices.And,inordertodeveloptestablecomponents,weneedtotakeadvantageoftheDImechanismforresolvingalltheirdependencies.

AcoredifferencebetweentheservicesinAngular2andAngularJS1.xisthewaytheirdependenciesarebeingresolvedandrepresentedinternally.AngularJS1.xisusingstringsforidentifyingthedifferentservicesandtheassociatedfactoriesusedfortheirinstantiation.However,Angular2useskeysinstead.Usuallythekeysarethetypesofthedistinctservices.Anothercoredifferenceintheinstantiationisthehierarchicalstructureofinjectors,whichencapsulatedifferentdependencyproviderswithdifferentvisibility.

Anotherdistinctionbetweentheservicesinthelasttwomajorversionsoftheframeworkisthesimplifiedsyntax.AlthoughAngular2usesES2015classesforthedefinitionofourbusinesslogic,youcanuseECMAScript5constructorfunctionsaswellorusetheDSLprovidedbytheframework.TheDIinAngular2hasacompletelydifferentsyntaxandhasimprovedbehaviorbyprovidingaconsistentwayofinjectingdependencies.ThesyntaxusedintheprecedingexampleusesES2016decorators,andinChapter5,DependencyInjectioninAngular2,we’lltakealookatalternativesyntax,whichusesECMAScript5.YoucanalsofindmoredetailedexplanationofAngular2servicesandDIinChapter5,DependencyInjectioninAngular2.

Page 96: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 97: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Understandingthenewcomponent-basedrouterIntraditionalwebapplications,allthepagechangesareassociatedwithafull-pagereload,whichfetchesallofthereferencedresourcesanddataandrenderstheentirepageontothescreen.However,requirementsforwebapplicationshaveevolvedovertime.

Single-pageapplications(SPAs)thatwebuildwithAngularsimulatedesktopuserexperiences.Thisofteninvolveincrementalloadingoftheresourcesanddatarequiredbytheapplication,andnofull-pagereloadsaftertheinitialpageload.OftenthedifferentpagesorviewsinSPAsarerepresentedbydifferenttemplates,whichareloadedasynchronouslyandrenderedonaspecificpositiononthescreen.Later,whenthetemplatewithalltherequiredresourcesisloadedandtherouteischanged,thelogicattachedtotheselectedpageisinvokedandpopulatesthetemplatewithdata.IftheuserpressestherefreshbuttonafterthegivenpageinourSPAisloaded,thesamepageneedstobere-renderedaftertherefreshoftheviewcompletes.Thisinvolvessimilarbehavior—findingtherequestedview,fetchingtherequiredtemplatewithallreferencedresources,andinvokingthelogicassociatedwiththatview.

Whattemplateneedstobefetched,andthelogicwhichshouldbeinvokedafterthepagereloadssuccessfully,dependsontheselectedviewbeforetheuserpressedtherefreshbutton.TheframeworkdeterminesthisbyparsingthepageURL,whichcontainstheidentifierofthecurrentlyselectedpage,representedinthehierarchicalstructure.

Alltheresponsibilitiesrelatedtothenavigation,changingtheURL,loadingtheappropriatetemplate,andinvokingspecificlogicwhentheviewisloadedareassignedtotheroutercomponent.Thesearesomequitechallengingtasks,andsupportfordifferentnavigationAPIsrequiredforcross-browsercompatibilitymakestheimplementationofroutinginmodernSPAsanon-trivialproblem.

AngularJS1.xintroducedtherouterinitscore,whichwaslaterexternalizedintothengRoutecomponent.ItallowsadeclarativewayfordefiningthedifferentviewsinourSPA,byprovidingatemplateforeachpageandapieceoflogicthatneedstobeinvokedwhenapageisselected.However,thefunctionalityoftherouterislimited.Itdoesnotsupportessentialfeaturessuchasnestedviewrouting.That’soneofthereasonsmostdeveloperspreferredtouseui-router,developedbythecommunity.BothAngularJS1.x’srouter,andui-router,route-definitionsincludearouteconfigurationobject,whichdefinesatemplateandacontrollerassociatedwiththepage.

Asdescribedintheprevioussections,Angular2changedthebuildingblocksitprovidesforthedevelopmentofSPAs.Angular2removesthefloatingcontrollers,andinsteadrepresentsviewsasacompositionofcomponents.Thisnecessitatesthedevelopmentofabrandnewrouter,whichempowersthesenewconcepts.

ThecoredifferencesbetweentheAngularJS1.xrouterandtheAngular2routerare:

TheAngular2routeriscomponentbased,ngRouteisnot.

Page 98: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Thereisnowsupportfornestedviews.DifferentsyntaxempoweredbyES2016decorators.

Page 99: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Angular2routedefinitionsyntaxLet’stakeabrieflookatthenewsyntaxusedbytheAngular2routertodefineroutesinourapplications:

import{Component}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

import{RouteConfig,ROUTER_DIRECTIVES,ROUTER_BINDINGS}from

'angular2/router';

import{Home}from'./components/home/home';

import{About}from'./components/about/about';

@Component({

selector:'app',

templateUrl:'./app.html',

directives:[ROUTER_DIRECTIVES]

})

@RouteConfig([

{path:'/',component:Home,name:'home'},

{path:'/about',component:About,name:'about'}

])

classApp{}

bootstrap(App,[ROUTER_PROVIDERS]);

Wewon’tgointotoomuchdetailheresinceChapter6,Angular2formsandthenewcomponent-basedrouterandChapter7,Buildingareal-lifeapplicationwhileexploringpipesandhttp,arededicatedtothenewrouter,butlet’smentionthemainpointsintheprecedingcodesnippet.

Therouterlivesinthemodule,angular2/router.There,wecanfindthedirectivesitdefines,thedecoratorusedfortheconfigurationoftheroutesandROUTER_PROVIDERS.

NoteWe’lltakeafurtherlookatROUTER_PROVIDERSinChapter7,Buildingareal-lifeapplicationwhileexploringpipesandhttp.

Theparameterpassedtothe@RouteConfigdecoratorshowshowwedefinetheroutesinourapplication.Weuseanarraywithobjects,whichdefinesthemappingsbetweenroutesandthecomponentsassociatedwiththem.InsidetheComponentdecorator,weexplicitlystatethatwewanttousethedirectivescontainedwithinROUTER_DIRECTIVES,whicharerelatedtotherouter’susageinsidethetemplates.

Page 100: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 101: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SummaryInthischapter,wetookaquickoverviewofthemainbuildingblocksfordevelopingSPAsprovidedbyAngular2.WepointedoutthecoredifferencesbetweenthesecomponentsinAngularJS1.xandAngular2.

AlthoughwecanuseES2015,orevenES5,forbuildingAngular2applications,therecommendationfromGoogleistotakeadvantageofthelanguageusedforthedevelopmentoftheframework—TypeScript.

Inthenextchapter,we’lltakealookatTypeScriptandhowwecanstartusingitinyournextapplication.WewillalsoexplainhowwecantakeadvantageofthestatictypingintheJavaScriptlibrariesandframeworkswritteninvanillaJavaScript,withambienttypeannotations.

Page 102: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 103: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Chapter3.TypeScriptCrashCourseInthischapter,wearegoingtostartworkingwithTypeScript,thelanguageAngular2recommendsforscripting.AllthefeaturesECMAScript2015andrespectivelyECMAScript2016provides,suchasfunctions,classes,modules,anddecorators,arealreadyimplementedinoraddedtotheroadmapofTypeScript.Becauseoftheextratypeannotations,therearesomesyntacticaladditionscomparedtoJavaScript.

Forsmoothertransitionfromthelanguagewealreadyknow-ES5,wewillstartwithsomecommonfeaturesbetweenES2016andTypeScript.WheretherearedifferencesbetweentheESsyntaxandTypeScript,we’llexplicitlymentionit.Inthesecondhalfofthechapter,we’lladdthetypeannotationstoeverythingwe’velearneduntilthispoint.

Laterinthechapter,wewillexplaintheextrafeaturesTypeScriptprovides,suchasstatictypingandextendedsyntax.Wewilldiscussthedifferentconsequencesbasedonthesefeatures,whichwillhelpusbemoreproductiveandlesserror-prone.Let’sgetgoing!

Page 104: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

IntroductiontoTypeScriptTypeScriptisanopensourceprogramminglanguagethatisdevelopedandmaintainedbyMicrosoft.ItsinitialpublicreleasewasinOctober2012.TypeScriptisasupersetofECMAScript,supportingallofthesyntaxandsemanticsofJavaScriptwithsomeextrafeaturesontop,suchasstatictypingandrichersyntax.

Fig.1showstherelationshipbetweenES5,ES2015,ES2016,andTypeScript.

Fig.1

BecauseTypeScriptisstaticallytyped,itcanprovideanumberofbenefitstousasJavaScriptdevelopers.Let’shaveaquicklookatthosebenefitsnow.

Page 105: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Compile-timetypecheckingSomeofthemostcommonmistakeswemakewhilewritingJavaScriptcodeistomisspellapropertyoramethodname.We’llfindoutaboutthemistakewhenwegetaruntimeerror.Thiscanhappenduringdevelopmentaswellasinproduction.Hopingwewillknowabouttheerrorbeforewedeployourcodetoproductionenvironmentisn’tacomfortablefeeling!However,thisisnotaproblemspecifictoJavaScript;itissomethingcommontoallthedynamiclanguages.Evenwithlotsofunittests,theseerrorscanslipby.

TypeScriptprovidesacompiler,whichtakescareofsuchmistakesforusbyusingstaticcodeanalysis.Ifwetakeadvantageofstatictyping,TypeScriptwillbeawareoftheexistingpropertiesagivenobjecthas,andifwemisspellanyofthem,thecompilerwillwarnuswithacompile-timeerror.

AnothergreatbenefitofTypeScriptisthatitallowslargeteamstocollaborate,sinceitprovidesformal,verifiablenaming.Thisway,itallowsustowriteeasy-to-understandcode.

Page 106: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

BettersupportbytexteditorsandIDEsThereareanumberoftools,suchasTernorGoogleClosureCompiler,thataretryingtobringbetterautocompletionsupportforJavaScriptintexteditorsandIDEs.However,asJavaScriptisadynamiclanguage,itisimpossiblefortheIDEsandtexteditorstomakesophisticatedsuggestionswithoutanymetadata.

Annotatingthecodewithsuchmetadataisabuilt-infeatureofTypeScriptknownastypeannotations.Basedonthem,texteditorsandIDEscanperformbetterstaticanalysisoverourcode.Thisprovidesbetterrefactoringtoolsandautocompletion,whichincreasesourproductivityandallowsustomakefewermistakeswhilewritingthesourcecodeforourapplications.

Page 107: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

There’sevenmoretoTypeScriptTypeScriptbyitselfhasanumberofotherbenefits:

ItisasupersetofJavaScript:AllJavaScript(ES5andES2015)programsarealreadyvalidTypeScriptones.Inessence,youhavealreadybeenwritingTypeScriptcode.SinceitisbasedonthelatestversionoftheECMAScriptstandard,itallowsustotakeadvantageofthelatestbleedingedgesyntaxprovidedbythelanguage.Supportsoptionaltypechecking:If,foranyreason,wedecidethatwedon’twanttoexplicitlydefinethetypeofavariableoramethod,wecanjustskipthetypedefinition.However,weshouldbeawarethatthismeanswearenolongertakingadvantageofthestatictyping,sowearegivinguponallthebenefitsmentionedearlier.DevelopedandmaintainedbyMicrosoft:Thequalityoftheimplementationofthelanguageisveryhighanditisunlikelythatsupportwillbedroppedunexpectedly.TypeScriptisbasedontheworkofsomeoftheworld’sbestexpertsinprogramminglanguagedevelopment.Itisopensource:Thisallowsthecommunitytofreelycontributetothelanguageandsuggestfeatures,whicharediscussedinanopenmanner.ThefactthatTypeScriptisopensourceallowsfortheeasierdevelopmentofthird-partyextensionsandtools,whichextendsfurtherthescopeofitsusage.

SincemodernbrowsersdonotsupportTypeScriptnatively,thereisacompilerthattranslatestheTypeScriptcodewewriteintoreadableJavaScriptinapredefinedtargetversionofECMAScript.Oncethecodeiscompiled,allthetypeannotationsareremoved.

Page 108: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 109: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingTypeScriptLet’sstartwritingsomeTypeScript!

Inthefollowingsections,wearegoingtotakealookatdifferentsnippetsshowingsomeofthefeaturesofTypeScript.Inordertobeabletorunthesnippetsandplaywiththemyourself,you’llneedtoinstalltheTypeScriptcompileronyourcomputer.Let’stakealookathowtodothis.

TypeScriptisbestinstalledusingNodePackageManager(npm).I’drecommendyoutousenpmVersion3.0.0ornewer.Ifyoudon’thavenode.jsandnpminstalledalready,youcanvisithttps://nodejs.organdfollowtheinstructionsthere.

Page 110: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

InstallingTypeScriptwithnpmOnceyouhavenpminstalledandrunning,verifythatyouhavethelatestversionbyopeningyourterminalwindowandrunningthefollowingcommand:

$npm–v

InordertoinstallTypeScript1.8,use:

[email protected]

TheprecedingcommandwillinstalltheTypeScriptcompilerandadditsexecutable(tsc)asglobaltoyourpath.

Inordertoverifythateverythingworksproperly,youcanuse:

$tsc–v

Version1.8.0

Theoutputshouldbesimilartotheprecedingone,thoughpossiblywithadifferentversion.

Page 111: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

RunningourfirstTypeScriptprogramNoteYoucanfindthecodeforthisbookonthefollowingURL:https://github.com/mgechev/switching-to-angular2.Asacommentinmostcodesnippetsyou’llfindarelativetotheappdirectoryfilepathwhereyoucanfindthem.

Now,let’scompileourfirstTypeScriptprogram!Createafilecalledhello.tsandenterthefollowingcontent:

//ch3/hello-world/hello-world.ts

console.log('Helloworld!');

Sinceyou’vealreadyinstalledtheTypeScriptcompiler,youshouldhaveaglobalexecutablecommandcalledtsc.Youcanuseitinordertocompilethefile:

$tschello.ts

Now,youshouldseethefilehello.jsinthesamedirectorywherehello.tsis.hello.jsistheoutputoftheTypeScriptcompiler;itcontainstheJavaScriptequivalenttotheTypeScriptyouwrote.Youcanrunthisfileusingthefollowingcommand:

$nodehello.js

Now,you’llseethestringHelloworld!printedonthescreen.Inordertocombinetheprocessofcompilingandrunningtheprogram,youcanusethepackagets-node:

$npminstall-tts-node

Nowyoucanrun:

$ts-nodehello.ts

Youshouldseethesameresult,butwithoutthets-nodefilestoredonthedisk.

Page 112: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 113: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TypeScriptsyntaxandfeaturesintroducedbyES2015andES2016AsTypeScriptisasupersetofJavaScript,beforewestartlearningaboutitssyntax,it’salittleeasiertostartbyintroducingsomeofthebiggerchangesinES2015andES2016;tounderstandTypeScript,wefirstmustunderstandES2015andES2016.We’regoingtohaveawhistle-stoptourthroughthesechangesbeforedivingintoTypeScriptproperlater.

AdetailedexplanationofES2015andES2016isoutsidethescopeofthisbook.Inordertogetfamiliarwithallthenewfeaturesandsyntaxes,IstronglyrecommendyoutotakealookatExploringES6:upgradetothenextversionofJavaScriptbyDr.AxelRauschmayer.

Thenextcoupleofpageswillintroducenewstandardsandallowyoutotakeadvantageofmostofthefeaturesyou’regoingtoneedinthedevelopmentofAngular2applications.

Page 114: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ES2015arrowfunctionsJavaScripthasfirstclassfunctions,whichmeansthattheycanbepassedaroundlikeanyothervalue:

//ch3/arrow-functions/simple-reduce.ts

varresult=[1,2,3].reduce(function(total,current){

returntotal+current;

},0);//6

Thissyntaxisgreat;however,itisabittooverbose.ES2015introducedanewsyntaxtodefineanonymousfunctionscalledthearrowfunctionsyntax.Usingit,wecancreateanonymousfunctions,asseeninthefollowingexamples:

//ch3/arrow-functions/arrow-functions.ts

//example1

varresult=[1,2,3]

.reduce((total,current)=>total+current,0);

console.log(result);

//example2

vareven=[3,1,56,7].filter(el=>!(el%2));

console.log(even);

//example3

varsorted=data.sort((a,b)=>{

vardiff=a.price-b.price;

if(diff!==0){

returndiff;

}

returna.total-b.total;

});

Inthefirstexample,wegotthetotalsumoftheelementsinthearray[1,2,3].Inthesecondexample,wegotalltheevennumbersinsidethearray[3,1,56,7].Inthethirdexample,wesortedanarraybytheproperties’priceandtotalintheascendingorder.

Arrowfunctionshaveafewmorefeaturesthatweneedtolookat.Themostimportantoneofthemisthattheykeepthecontext(this)fromthesurroundingcode:

//ch3/arrow-functions/context-demo.ts

functionMyComponent(){

this.age=42;

setTimeout(()=>{

this.age+=1;

console.log(this.age);

},100);

}

newMyComponent();//43in100ms.

Page 115: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Forexample,whenweinvokethefunctionMyComponentwiththeoperatornew,thiswillpointtothenewobjectinstantiatedbythecall.Thearrowfunctionwillkeepthecontext(this),inthecallbackofsetTimeout,andprint43onthescreen.

ThisisextremelyusefulinAngular2,sincethebindingcontextforagivencomponentisitsinstance(thatis,itsthis).IfwedefineMyComponentasanAngular2componentandwehaveabindingtotheageproperty,theprecedingcodewillbevalidandallthebindingswillwork(noticethatwedon’thavescope,neitherdowehaveexplicitcallstothe$digestloopalthoughwehavecalledsetTimeoutdirectly).

Page 116: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingtheES2015andES2016classesWhendevelopersnewtoJavaScripthearthatthelanguageempowerstheobject-oriented(OO)paradigm,they’renormallyconfusedwhentheydiscoverthatthere’snosyntaxforthedefinitionofclasses.Thisperceptionwasbornbythefactthatsomeofthemostpopularprogramminglanguages,suchasJava,C#,andC++,havetheconceptofclassesusedfortheconstructionofobjects.However,JavaScriptimplementstheOOparadigmdifferently.JavaScripthasaprototype-based,object-orientedprogrammingmodel,wherewecaninstantiateobjectsusingtheobjectliteralsyntaxorfunctions(alsoknownastheconstructorfunctions)andwecantakeadvantageoftheinheritanceusingtheso-calledprototypechain.

ThoughthisisavalidwaytoimplementtheOOparadigmandthesemanticsaresimilartotheoneintheclassicalobject-orientedmodel,itisconfusingforinexperiencedJavaScriptdeveloperswhoarenotsurehowtoprocessthisproperly.ThisisoneofthereasonsTC39decidedtoprovideanalternativesyntaxtoexploittheobject-orientedparadigminthelanguage.Behindthescenes,thenewsyntaxhasthesamesemanticsastheonewe’reusedto,likeusingtheconstructorfunctionsandtheprototype-basedinheritance.However,itprovidesamoreconvenientsyntaxtoempowertheOOparadigm’sfeatureswithlessboilerplate.

ES2016addssomeextrasyntaxtotheES2015classes,suchasstaticandinstancepropertydeclaration.

HereisanexamplethatdemonstratesthesyntaxusedtodefinetheclassesinES2016:

//ch3/es6-classes/sample-classes.ts

classHuman{

statictotalPeople=0;

_name;//ES2016propertydeclarationsyntax

constructor(name){

this._name=name;

Human.totalPeople+=1;

}

getname(){

returnthis._name;

}

setname(val){

this._name=val;

}

talk(){

return`Hi,I'm${this.name}!`;

}

}

classDeveloperextendsHuman{

_languages;//ES2016propertydeclarationsyntax

constructor(name,languages){

super(name);

this._languages=languages;

}

Page 117: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

getlanguages(){

returnthis._languages;

}

talk(){

return`${super.talk()}AndIknow

${this.languages.join(',')}.`;

}

}

InES2015,theexplicitdeclarationofthe_namepropertyisnotrequired;however,sincetheTypeScriptcompilershouldbeawareduringcompile-timeoftheexistingpropertiesoftheinstancesofagivenclass,wewouldneedtoaddthedeclarationofthepropertytotheclassdeclarationitself.

TheprecedingsnippetisbothavalidTypeScriptandJavaScriptcode.Init,wedefinedaclasscalledHuman,whichaddsasinglepropertytotheobjectsinstantiatedbyit.Itdoesthisbysettingitsvaluetotheparameternamepassedtoitsconstructor.

Now,openthech3/es6-classes/sample-classes.tsfileandplayaroundwithit!Youcancreatedifferentinstancesoftheclassesthesamewayyoucreateobjectsusingconstructorfunctions:

varhuman=newHuman("foobar");

vardev=newDeveloper("bar",["JavaScript"]);

console.log(dev.talk());

Inordertoexecutethecode,runthefollowingcommand:

$ts-nodesample-classes.ts

ClassesarecommonlyusedinAngular2.Youcanusethemtodefineyourcomponents,directives,services,andpipes.However,youcanalsousethealternativeES5syntax,whichtakesadvantageoftheconstructorfunctions.Underthehood,oncetheTypeScriptcodeiscompiled,therewouldbenosuchsignificantdifferencebetweenboththesyntaxes,becausetheES2015classesarebeingtranspiledtoconstructorfunctionsanyway.

Page 118: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningvariableswithblockscopeAnotherconfusingpointofJavaScriptfordeveloperswithadifferentbackgroundisthevariablescopeinthelanguage.InJavaandC++,forexample,we’reusedtotheblocklexicalscope.Thismeansthatagivenvariabledefinedinsideaspecificblockwillbevisibleonlyinsidethatblockandallofthenestedblocksinsideofit.

However,inJavaScript,thingsarealittlebitdifferent.ECMAScriptdefinesafunctionallexicalscopethathassimilarsemanticstotheblocklexicalscope,butitusesfunctionsinsteadofblocks.Thismeansthatwehavethefollowing:

//ch3/let/var.ts

varfns=[];

for(vari=0;i<5;i+=1){

fns.push(function(){

console.log(i);

})

}

fns.forEach(fn=>fn());

Thishassomeweirdimplications.Oncethecodehasbeenexecuted,itwilllogfivetimesthenumber5.

ES2015addedanewsyntaxtodefinethevariableswithblock-scopevisibility.Thesyntaxissimilartothecurrentone.However,insteadofvar,itusesthekeywordlet:

//ch3/let/let.ts

varfns=[];

for(leti=0;i<5;i+=1){

fns.push(function(){

console.log(i);

})

}

fns.forEach(fn=>fn());

Page 119: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 120: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Meta-programmingwithES2016decoratorsJavaScriptisadynamiclanguagethatallowsustoeasilymodifyand/oralterthebehaviortosuittheprogramswewrite.DecoratorsareaproposaltoES2016,whichaccordingtothedesigndocumenthttps://github.com/wycats/javascript-decorators:

“…makeitpossibletoannotateandmodifyclassesandpropertiesatdesigntime.”

TheirsyntaxesarequitesimilartotheannotationsinJava,andtheyareevenclosertothedecoratorsinPython.ES2016decoratorsareusedcommonlyinAngular2todefinecomponents,directives,andpipes,andtotakeadvantageofthedependencyinjectionmechanismoftheframework.Essentially,mostusecasesofdecoratorsinvolvealteringthebehaviortopredefinedlogicoraddingsomemetadatatodifferentconstructs.

ES2016decoratorsallowustodoalotoffancythingsbychangingthebehaviorofourprograms.Typicalusecasescouldbetoannotatethegivenmethodsorpropertiesasdeprecatedorread-only.AsetofpredefineddecoratorsthatcanimprovethereadabilityofthecodeweproducecanbefoundinaprojectbyJayPhelpscalledcore-decorators.js.Anotherusecaseistakingadvantageoftheproxy-basedaspect-orientedprogrammingusingadeclarativesyntax.Thelibraryprovidingthisfunctionalityisaspect.js.

Ingeneral,ES2016decoratorsarejustanothersyntaxsugar,whichtranslatestothecodewe’realreadyfamiliarwithfromthepreviousversionsofJavaScript.Let’stakealookatasimpleexamplefromtheproposal’sdraft:

//ch3/decorators/nonenumerable.ts

classPerson{

@nonenumerable

getkidCount(){

return42;

}

}

functionnonenumerable(target,name,descriptor){

descriptor.enumerable=false;

returndescriptor;

}

varperson=newPerson();

for(letpropinperson){

console.log(prop);

}

Inthiscase,wehaveanES2015classcalledPersonwithasinglegettercalledkidCount.OverthekidCountgetter,wehaveappliedthenonenumerabledecorator.Thedecoratorisafunctionthatacceptsatarget(thePersonclass),thenameofthetargetpropertywe

Page 121: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

intendtodecorate(kidCount),andthedescriptorofthetargetproperty.Afterwechangethedescriptor,weneedtoreturnitinordertoapplythemodification.Basically,thedecorator’sapplicationcouldbetranslatedintoECMAScript5inthefollowingway:

descriptor=nonenumerable(Person.prototype,'kidCount',descriptor)||

descriptor;

Object.defineProperty(Person.prototype,'kidCount',descriptor);

Page 122: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingconfigurabledecoratorsHereisanexampleonusingthedecoratorsdefinedbyAngular2:

@Component({

selector:'app',

providers:[NamesList],

templateUrl:'./app.html',

directives:[RouterOutlet,RouterLink]

})

@RouteConfig([

{path:'/',component:Home,name:'home'},

{path:'/about',component:About,name:'about'}

])

exportclassApp{}

Whendecoratorsacceptarguments(justlikeComponent,RouteConfig,andViewintheprecedingexample),theyneedtobedefinedasfunctionsthatacceptargumentsandreturntheactualdecorator:

functionComponent(config){

//validateproperties

return(componentCtrl)=>{

//applydecorator

};

}

Inthisexample,wedefinedaconfigurabledecoratorcalledComponentthatacceptsasingleargumentcalledconfigandreturnsadecorator.

Page 123: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 124: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WritingmodularcodewithES2015AnotherproblemthatJavaScriptprofessionalshaveexperiencedalongtheyearsisthelackofamodulesysteminthelanguage.Initially,thecommunitydevelopeddifferentpatterns,aimingtoenforcethemodularityandtheencapsulationofthesoftwareweproduce.Suchpatternsincludedthemodulepattern,whichtakesadvantageofthefunctionallexicalscopeandclosures.Anotherexampleisthenamespacepattern,whichrepresentsthedifferentnamespacesasnestedobjects.AngularJS1.xintroduceditsownmodulesystemthatunfortunatelydoesn’tprovidefeatureslikelazymoduleloading.However,thesepatternsweremorelikeworkaroundsratherthanrealsolutions.

CommonJS(usedinnode.js)andAMD(AsynchronousModuleDefinition)werelaterinvented.Theyarestillinwideusetodayandprovidefeatures,suchashandlingofcirculardependencies,asynchronousmoduleloading(inAMD),andsoon.

TC39tookthebestoftheexistingmodulesystemsandintroducedthisconceptonalanguagelevel.ES2015providestwoAPIstodefineandconsumemodules.Theyareasfollows:

DeclarativeAPI.ImperativeAPIusingthemoduleloader.

Angular2takesfulladvantageoftheES2015modulesystem,solet’sdiveintoit!Inthissection,wearegoingtotakealookatthesyntaxusedforthedeclarativedefinitionandconsumptionofmodules.Wearealsogoingtopeekatthemoduleloader’sAPIinordertoseehowwecanprogrammaticallyloadmodulesinanexplicitasynchronousmanner.

Page 125: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingtheES2015modulesyntaxLet’stakealookatanexample:

//ch3/modules/math.ts

exportfunctionsquare(x){

returnMath.pow(x,2);

};

exportfunctionlog10(x){

returnMath.log10(x);

};

exportconstPI=Math.PI;

Intheprecedingsnippet,wedefinedasimpleES2015moduleinthefilemath.ts.WecanthinkofitasasamplemathAngular2utilitymodule.Insideit,wedefinedandexportedthefunctionssquareandlog10,andtheconstantPI.TheconstkeywordisanotherkeywordbroughtbyES2015thatisusedtodefineconstants.Asyoucansee,whatwedoisnothingmorethanprefixingthefunction’sdefinitionswiththekeywordexport.Ifwewanttoexporttheentirefunctionalityintheendandskiptheduplicateexplicitusageofexport,wecan:

//ch3/modules/math2.ts

functionsquare(x){

returnMath.pow(x,2);

};

functionlog10(x){

returnMath.log10(x);

};

constPI=Math.PI;

export{square,log10,PI};

Thesyntaxonthelastlineisnothingmorethananenhancedobjectliteralsyntax,introducedbyES2015.Now,let’stakealookathowwecanconsumethismodule:

//ch3/modules/app.ts

import{square,log10}from'./math';

console.log(square(2));//4

console.log(log10(10));//1

Asanidentifierofthemodule,weuseditsrelativepathtothecurrentfile.Byusingdestructuring,weimportedtherequiredfunctions—inthiscase,squareandlog10.

Page 126: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TakingadvantageoftheimplicitasynchronousbehaviorItisimportanttonotethattheES2015modulesyntaxhasimplicitasynchronousbehavior.

Let’ssaywehavemodulesA,B,andC.ModuleAusesmodulesBandC,soitdependsonthem.OncetheuserrequiresmoduleA,theJavaScriptmoduleloaderwouldneedtoloadmodulesBandCbeforebeingabletoinvokeanyofthelogicthatresidesinmoduleAbecauseofthedependencieswehave.However,modulesBandCwillbeloadedasynchronously.Oncetheyareloadedcompletely,theJavaScriptvirtualmachinewillbeabletoexecutemoduleA.

Page 127: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingaliasesAnothertypicalsituationiswhenwewanttouseanaliasforagivenexport.Forexample,ifweuseathird-partylibrary,wemaywanttorenameanyofitsexportsinordertoescapenamecollisionsorjusttohaveamoreconvenientnaming:

import{bootstrapasinitialize}from'angular2/platform/browser';

Page 128: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ImportingallthemoduleexportsWecanimporttheentiremathmoduleusing:

//ch3/modules/app2.ts

import*asmathfrom'./math';

console.log(math.square(2));//4

console.log(math.log10(10));//1

console.log(math.PI);//3.141592653589793

ThesemanticsbehindthissyntaxisquitesimilartoCommonJS,althoughinthebrowser,wehaveimplicitasynchronousbehavior.

Page 129: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefaultexportsIfagivenmoduledefinesanexport,whichwouldquitelikelybeusedbyanyofitsconsumermodules,wecantakeadvantageofthedefaultexportsyntax:

//ch3/modules/math3.ts

exportdefaultfunctioncube(x){

returnMath.pow(x,3);

};

exportfunctionsquare(x){

returnMath.pow(x,2);

};

Inordertoconsumethismodule,wecanusethefollowingapp.tsfile:

//ch3/modules/app3.ts

importcubefrom'./math3';

console.log(cube(3));//27

Or,ifwewanttoimportthedefaultexportaswellassomeotherexports,wecanuse:

//ch3/modules/app4.ts

importcube,{square}from'./math3';

console.log(square(2));//4

console.log(cube(3));//27

Ingeneral,thedefaultexportisnothingmorethananamedexportnamedwiththereservedworddefault:

//ch3/modules/app5.ts

import{defaultascube}from'./math3';

console.log(cube(3));//27

Page 130: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 131: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ES2015moduleloaderThenewversionofthestandarddefinesaprogrammaticAPItoworkwithmodules.Thisistheso-calledmoduleloaderAPI.Itallowsustodefineandimportmodules,orconfigurethemoduleloading.

Let’ssupposewehavethefollowingmoduledefinitioninthefileapp.js:

import{square}from'./math';

exportfunctionmain(){

console.log(square(2));//4

}

Fromthefileinit.js,wecanprogrammaticallyloadtheappmoduleandinvokeitsmainfunctionusing:

System.import('./app')

.then(app=>{

app.main();

})

.catch(error=>{

console.log('Terribleerrorhappened',error);

});

TheglobalobjectSystemhasamethodcalledimportthatallowsustoimportmodulesusingtheiridentifier.Intheprecedingsnippet,weimportedthemoduleappdefinedinapp.js.System.importreturnsapromisethatcouldberesolvedonsuccessorrejectedincaseofanerror.Oncethepromiseisresolvedasthefirstparameterofthecallbackpassedtothen,wewillgetthemoduleitself.Thefirstparameterofthecallbackregisteredincaseofrejectionistheerrorthathappened.

ThecodefromthelastsnippetdoesnotexistintheGitHubrepository,sinceitrequiressomeadditionalconfiguration.WearegoingtoapplythemoduleloadermoreexplicitlyintheAngular2examplesinthenextchaptersofthebook.

Page 132: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 133: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ES2015andES2016recapCongratulations!We’remorethanhalfwaytowardlearningTypeScript.Allthefeatureswe’vejustseenareapartofTypeScript,sinceitimplementsasupersetofJavaScriptandsinceallthesefeaturesareanupgradeontopofthecurrentsyntax,theyareeasytograspbyexperiencedJavaScriptdevelopers.

Inthenextsections,wewilldescribealltheamazingfeaturesofTypeScriptthatareoutsidetheintersectionwithECMAScript.

Page 134: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 135: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TakingadvantageofstatictypingStatictypingiswhatcanprovidebettertoolingforourdevelopmentprocess.WhilewritingJavaScript,themostthatIDEsandtexteditorscandoissyntaxhighlightingandprovidingsomebasicautocompletionsuggestionsbasedonthesophisticatedstaticanalysisofourcode.Thismeansthatwecanonlyverifythatwehaven’tmadeanytyposbyrunningthecode.

Intheprevioussections,wedescribedonlythenewfeaturesprovidedbyECMAScriptexpectedtobeimplementedbybrowsersinthenearfuture.Inthissection,wewilltakealookatwhatTypeScriptprovidesinordertohelpusbelesserror-proneandmoreproductive.Atthetimeofthiswriting,there’renoplanstoimplementbuilt-insupportforstatictypinginthebrowsers.

TheTypeScriptcodegoesthroughintermediatepreprocessingthatperformsthetypecheckinganddropsallthetypeannotationsinordertoprovidevalidJavaScriptsupportedbymodernbrowsers.

Page 136: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingexplicittypedefinitionsJustlikeJavaandC++,TypeScriptallowsustoexplicitlydeclarethetypeofthegivenvariable:

letfoo:number=42;

Theprecedinglinedefinesthevariablefoointhecurrentblockusingtheletsyntax.Weexplicitlydeclarethatwewantfootobeofthetypenumberandwesetthevalueoffooto42.

Nowlet’strytochangethevalueoffoo:

letfoo:number=42;

foo='42';

Here,afterthedeclarationoffoo,wewillsetitsvaluetothestring'42'.ThisisaperfectlyvalidJavaScriptcode;however,ifwecompileitusingtheTypeScript’scompiler,wewillget:

$tscbasic.ts

basic.ts(2,1):errorTS2322:Type'string'isnotassignabletotype

'number'.

Oncefoohasbeenassociatedwiththegiventype,wecannotassignitvaluesbelongingtodifferenttypes.Thisisoneofthereasonswecanskiptheexplicittypedefinitionincaseweassignavaluetothegivenvariable:

letfoo=42;

foo='42';

ThesemanticsbehindthiscodewillbethesameastheonewiththeexplicittypedefinitionbecauseofthetypeinferenceofTypeScript.We’llfurthertakealookatitattheendofthischapter.

ThetypeanyAllthetypesinTypeScriptaresubtypesofatypecalledany.Wecandeclarevariablesbelongingtotheanytypebyusingtheanykeyword.Suchvariablescanholdthevalueofanytype:

letfoo:any;

foo={};

foo='bar';

foo+=42;

console.log(foo);//"bar42"

TheprecedingcodeisavalidTypeScript,anditwillnotthrowanyerrorduringcompilationorruntime.Ifweusethetypeanyforallofourvariables,wewillbebasicallywritingthecodewithdynamictyping,whichdropsallthebenefitsoftheTypeScript’scompiler.That’swhywehavetobecarefulwithanyanduseitonlywhenitisnecessary.

AlltheothertypesinTypeScriptbelongtooneofthefollowingcategories:

Page 137: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Primitivetypes:ThisincludesNumber,String,Boolean,Void,Null,Undefined,andEnumtypes.Uniontypes:Uniontypesareoutofthescopeofthisbook.YoucantakealookattheminthespecificationofTypeScript.Objecttypes:ThisincludesFunctiontypes,classesandinterfacetypereferences,arraytypes,tupletypes,functiontypes,andconstructortypes.Typeparameters:ThisincludesGenericsthataregoingtobedescribedintheWritinggenericcodebyusingtypeparameterssection.

Page 138: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UnderstandingthePrimitivetypesMostoftheprimitivetypesinTypeScriptaretheoneswearealreadyfamiliarwithinJavaScript:Number,String,Boolean,Null,andUndefined.So,wearegoingtoskiptheirformalexplanationhere.AnothersetoftypesthatishandywhiledevelopingAngular2applicationsistheEnumtypesdefinedbyusers.

TheEnumtypesTheEnumtypesareprimitiveuser-definedtypesthat,accordingtothespecification,aresubclassesofNumber.TheconceptofenumsexistsintheJava,C++,andC#languages,andithasthesamesemanticsinTypeScript—user-definedtypesconsistingofsetsofnamedvaluescalledelements.InTypeScript,wecandefineenumusingthefollowingsyntax:

enumSTATES{

CONNECTING,

CONNECTED,

DISCONNECTING,

WAITING,

DISCONNECTED

};

ThisisgoingtobetranslatedtothefollowingJavaScript:

varSTATES;

(function(STATES){

STATES[STATES["CONNECTING"]=0]="CONNECTING";

STATES[STATES["CONNECTED"]=1]="CONNECTED";

STATES[STATES["DISCONNECTING"]=2]="DISCONNECTING";

STATES[STATES["WAITING"]=3]="WAITING";

STATES[STATES["DISCONNECTED"]=4]="DISCONNECTED";

})(STATES||(STATES={}));

Wecanusetheenumtypeasfollows:

if(this.state===STATES.CONNECTING){

console.log('Thesystemisconnecting');

}

Page 139: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UnderstandingtheObjecttypesInthissection,we’regoingtotakealookattheArraytypesandFunctiontypes,whichbelongtothemoregenericclassofObjecttypes.Wewillalsoexplorehowwecandefineclassesandinterfaces.TupletypeswereintroducedbyTypeScript1.3,andtheirmainpurposeistoallowthelanguagetobegintypingthenewfeaturesintroducedbyES2015,suchasdestructuring.Wewillnotdescribetheminthisbook.Forfurtherreadingyoucantakealookatthelanguage’sspecificationathttp://www.typescriptlang.org.

TheArraytypesInTypeScript,arraysareJavaScriptarrayswithacommonelementtype.Thismeansthatwecannothaveelementsfromdifferenttypesinagivenarray.Wehavedifferentarraytypesforallthebuilt-intypesinTypeScript,plusallthecustomtypesthatwedefine.

Wecandefineanarrayofnumbersasfollows:

letprimes:number[]=[];

primes.push(2);

primes.push(3);

Ifwewanttohaveanarray,whichseemsheterogeneous,similartothearraysinJavaScript,wecanusethetypereferencetoany:

letrandomItems:any[]=[];

randomItems.push(1);

randomItems.push("foo");

randomItems.push([]);

randomItems.push({});

Thisispossible,sincethetypesofallthevalueswe’repushingtothearrayaresubtypesoftheanytypeandthearraywe’vedeclaredcontainsvaluesofthetypeany.

Wecanusethearraymethodswe’refamiliarwithinJavaScriptwithalltheTypeScriptArraytypes:

letrandomItems:any[]=[];

randomItems.push("foo");

randomItems.push("bar");

randomItems.join('');//foobar

randomItems.splice(1,0,"baz");

randomItems.join('');//foobazbar

Wealsohavethesquare-bracketsoperatorthatgivesusrandomaccesstothearray’selements:

letrandomItems:any[]=[];

randomItems.push("foo");

randomItems.push("bar");

randomItems[0]==="foo"

randomItems[1]==="bar"

TheFunctiontypes

Page 140: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Thefunctiontypesareasetofallthefunctionswithdifferentsignatures,includingthedifferentnumberofarguments,differentarguments’types,ordifferenttypesofthereturnresult.

We’realreadyfamiliarwithhowtocreateanewfunctioninJavaScript.Wecanusefunctionexpressionorfunctiondeclaration:

//functionexpression

varisPrime=function(n){

//body

};

//functiondeclaration

functionisPrime(n){

//body

};

Or,wecanusethenewarrowfunctionsyntax:

varisPrime=n=>{

//body

};

TheonlythingTypeScriptaltersisthefeaturetodefinethetypesofthefunction’sargumentsandthetypeofitsreturnresult.Afterthecompilerofthelanguageperformsitstypecheckingandtranspilation,allthetypeannotationswillberemoved.Ifweusefunctionexpressionandweassignafunctiontoavariable,wewillbeabletodefinethevariabletypeinthefollowingway:

letvariable:(arg1:type1,arg2:type2,…,argn:typen)=>returnType

Forexample:

letisPrime:(n:number)=>boolean=n=>{

//body

};

Incaseoffunctiondeclaration,we’llhave:

functionisPrime(n:number):boolean{

//body

}

Ifwewanttodefineamethodinaobjectliteral,wecanprocessitinthefollowingway:

letmath={

squareRoot(n:number):number{

//…

},

};

Intheprecedingexample,wedefinedanobjectliteralusingtheES2015syntaxthatdefinesthemethodsquareRoot.

Incasewewanttodefineafunctionthatproducessomesideeffectsinsteadofreturningaresult,wecandefineitasavoidfunction:

Page 141: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

letperson={

_name:null,

setName(name:string):void{

this._name=name;

}

};

Page 142: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningclassesTypeScriptclassesaresimilartowhatES2015offers.However,italtersthetypedeclarationsandcreatesmoresyntaxsugar.Forexample,let’staketheHumanclasswedefinedearlierandmakeitavalidTypeScriptclass:

classHuman{

statictotalPeople=0;

_name:string;

constructor(name){

this._name=name;

Human.totalPeople+=1;

}

getname(){

returnthis._name;

}

setname(val){

this._name=val;

}

talk(){

return`Hi,I'm${this.name}!`;

}

}

ThereisnodifferencebetweenthecurrentTypeScriptdefinitionwiththeonewealreadyintroduced,however,inthiscasethedeclarationofthe_namepropertyismandatory.Hereishowwecanusetheclass:

lethuman=newHuman('foo');

console.log(human._name);

Page 143: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingaccessmodifiersSimilarly,formostconventionalobject-orientedlanguagesthatsupportclasses,TypeScriptallowsdefinitionofaccessmodifiers.Inordertodenydirectaccesstothe_namepropertyoutsidetheclassitisdefinedin,wecandeclareitasprivate:

classHuman{

statictotalPeople=0;

private_name:string;

//…

}

ThesupportedaccessmodifiersbyTypeScriptare:

Public:Allthepropertiesandmethodsdeclaredaspubliccouldbeaccessedanywhere.Private:Allthepropertiesandmethodsdeclaredasprivatecanbeaccessedonlyfrominsidetheclass’definitionitself.Protected:Allthepropertiesandmethodsdeclaredasprotectedcanbeaccessedfrominsidetheclass’definitionorthedefinitionofanyotherclassextendingtheonethatownsthepropertyorthemethod.

AccessmodifiersareagreatwaytoimplementAngular2serviceswithgoodencapsulationandawell-definedinterface.Inordertounderstanditbetter,let’stakealookatanexampleusingtheclass’hierarchydefinedearlier,whichisportedtoTypeScript:

classHuman{

statictotalPeople=0;

constructor(protectedname:string,privateage:number){

Human.totalPeople+=1;

}

talk(){

return`Hi,I'm${this.name}!`;

}

}

classDeveloperextendsHuman{

constructor(name:string,privatelanguages:string[],age:number){

super(name,age);

}

talk(){

return`${super.talk()}AndIknow${this.languages.join(',')}.`;

}

}

JustlikeES2015,TypeScriptsupportstheextendskeywordanddesugarsittotheprototypalJavaScriptinheritance.

Intheprecedingexample,wesettheaccessmodifiersofthenameandagepropertiesdirectlyinsidetheconstructorfunction.Thesemanticsbehindthissyntaxdiffersfromtheoneusedinthepreviousexample.Ithasthefollowingmeaning:defineaprotected

Page 144: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

propertycallednameofthetypestringandassignthefirstvaluepassedtotheconstructorcalltoit.Itisthesamefortheprivateageproperty.Thissavesusfromexplicitlysettingthevalueintheconstructoritself.IfwetakealookattheconstructoroftheDeveloperclass,wecanseethatwecanusethemixturebetweenthesesyntaxes.Wecanexplicitlydefinethepropertyintheconstructor’ssignatureorwecanonlydefinethattheconstructoracceptstheparametersofthegiventypes.

Now,let’screateanewinstanceoftheDeveloperclass:

letdev=newDeveloper("foo",["JavaScript","Go"],42);

dev.languages=["Java"];

Duringcompilation,TypeScriptwillthrowanerrortellingusthatPropertylanguagesisprivateandonlyaccessibleinsideclass“Developer”.Now,let’sseewhat’sgoingtohappenifwecreateanewHumanclassandtrytoaccessitspropertiesfromoutsideitsdefinition:

lethuman=newHuman("foo",42);

human.age=42;

human.name="bar";

Inthiscase,we’llgetthefollowingtwoerrors:

Propertyageisprivateandisonlyaccessibleinsideclass“Human”andthePropertynameisaprotectedandonlyaccessibleinsideclass“Human”anditssubclasses.

However,ifwetrytoaccessthe_namepropertyfrominsidethedefinitionofDeveloper,thecompilerwon’tthrowanyerrors.

InordertogetabettersenseofwhattheTypeScriptcompilerwillproduceoutofatypeannotatedclass,let’stakealookattheJavaScriptproducedbythefollowingdefinition:

classHuman{

constructor(privatename:string){}

}

TheresultingECMAScript5willbe:

varHuman=(function(){

functionHuman(name){

this.name=name;

}

returnHuman;

})();

Thedefinedpropertyisaddeddirectlytotheobjectsinstantiatedbycallingtheconstructorfunctionwiththeoperatornew.Thismeansthatoncethecodeiscompiled,wecandirectlyaccesstheprivatemembersofthecreatedobjects.Inordertowrapthisup,accessmodifiersareaddedinthelanguageinordertohelpusenforcebetterencapsulationandgetcompile-timeerrorsincaseweviolateit.

Page 145: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefininginterfacesSubtypinginprogramminglanguagesallowsustotreatobjectsinthesamewaybasedontheobservationthattheyarespecializedversionsofagenericobject.Thisdoesn’tmeanthattheyhavetobeinstancesofthesameclassofobjects,orthattheyhavecompleteintersectionbetweentheirinterfaces.Theobjectsmighthaveonlyafewcommonpropertiesandstillbetreatedthesamewayinaspecificcontext.InJavaScript,weusuallyuseducktyping.Wemayinvokespecificmethodsforalltheobjectspassedtoafunctionbasedontheassumptionthatthesemethodsexist.However,allofushaveexperiencedtheundefinedisnotafunctionerrorthrownbytheJavaScriptinterpreter.

Object-orientedprogrammingandTypeScriptcomewithasolution.Theyallowustomakesureourobjectshavesimilarbehavioriftheyimplementinterfacesthatdeclarethesubsetofthepropertiestheyown.

Forexample,wecandefineourinterfaceAccountable:

interfaceAccountable{

getIncome():number;

}

Now,wecanmakesurebothIndividualandFirmimplementthisinterfacebydoingasfollows:

classFirmimplementsAccountable{

getIncome():number{

//…

}

}

classIndividualimplementsAccountable{

getIncome():number{

//…

}

}

Incaseweimplementagiveninterface,weneedtoprovideimplementationforallthemethodsdefinedinsideit,otherwisetheTypeScriptcompilerwillthrowanerror.Themethodsweimplementmusthavethesamesignatureastheonesdeclaredintheinterfacedefinition.

TypeScriptinterfacesalsosupportproperties.IntheAccountableinterface,wecanincludeafieldcalledaccountNumberwithatypeofstring:

interfaceAccountable{

accountNumber:string;

getIncome():number;

}

Wecandefineitinourclassasafieldoragetter.

InterfaceinheritanceInterfacesmayalsoextendeachother.Forexample,wemayturnourIndividualclass

Page 146: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

intoaninterfacethathasasocialsecuritynumber:

interfaceAccountable{

accountNumber:string;

getIncome():number;

}

interfaceIndividualextendsAccountable{

ssn:string;

}

Sinceinterfacessupportmultipleinheritances,IndividualmayalsoextendtheinterfaceHumanthathasthenameandageproperties:

interfaceAccountable{

accountNumber:string;

getIncome():number;

}

interfaceHuman{

age:number;

name:number;

}

interfaceIndividualextendsAccountable,Human{

ssn:string;

}

ImplementingmultipleinterfacesIncasetheclass’sbehaviorisaunionofthepropertiesdefinedinacoupleofinterfaces,itmayimplementallofthem:

classPersonimplementsHuman,Accountable{

age:number;

name:string;

accountNumber:string;

getIncome():number{

//...

}

}

Inthiscase,weneedtoprovidetheimplementationofallthemethodsdeclaredinsidetheinterfacesourclassimplements,otherwisethecompilerwillthrowacompile-timeerror.

Page 147: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 148: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

FurtherexpressivenesswithTypeScriptdecoratorsInES2015,weareabletodecorateonlyclasses,properties,methods,getters,andsetters.TypeScripttakesthisfurtherbyallowingustodecoratefunctionsormethodparameters:

classHttp{

//…

}

classGitHubApi{

constructor(@Inject(Http)http){

//…

}

}

However,theparameterdecoratorsshouldnotalteranyadditionalbehavior.Instead,theyareusedtogeneratemetadata.ThemosttypicalusecaseofthesedecoratorsisthedependencyinjectionmechanismofAngular2.

Page 149: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 150: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WritinggenericcodebyusingtypeparametersInthebeginningofthesectiononusingstatictyping,wementionedthetypeparameters.Inordertogetabetterunderstandingofthem,let’sbeginwithanexample.Let’ssupposewewanttoimplementtheclassicaldata-structureBinarySearchTree.Let’sdefineitsinterfaceusingaclasswithoutapplyinganymethodimplementations:

classNode{

value:any;

left:Node;

right:Node;

}

classBinarySearchTree{

privateroot:Node;

insert(any:value):void{/*…*/}

remove(any:value):void{/*…*/}

exists(any:value):boolean{/*…*/}

inorder(callback:{(value:any):void}):void{/*…*/}

}

Intheprecedingsnippet,wedefinedaclasscalledNode.Theinstancesofthisclassrepresenttheindividualnodesinourtree.Eachnodehasaleftandarightchildnodeandavalueofthetypeany;weuseanyinordertobeabletostoredataofanytypeinsideournodesandrespectivelyinsideBinarySearchTree.

Althoughtheearlierimplementationlooksreasonable,we’regivinguponusingthemostimportantfeaturethatTypeScriptprovides—statictyping.ByusinganyasatypeofthevaluefieldinsidetheNodeclass,wecan’ttakecompleteadvantageofthecompile-timetypechecking.ThisalsolimitsthefeaturesthatIDEsandtexteditorsprovidewhenweaccessthevaluepropertyoftheinstancesoftheNodeclass.

TypeScriptcomeswithanelegantsolutionthatisalreadywidelypopularintheworldofstatictyping—typeparameters.Usinggenerics,wecanparameterizetheclasseswecreatewiththetypeparameters.Forexample,wecanturnourNodeclassintothefollowing:

classNode<T>{

value:T;

left:Node<T>;

right:Node<T>;

}

Node<T>indicatesthatthisclasshasasingletypeparametercalledTthatisusedsomewhereinsidetheclass’sdefinition.WecanuseNodebydoingasfollows:

letnumberNode=newNode<number>();

letstringNode=newNode<string>();

numberNode.right=newNode<number>();

numberNode.value=42;

numberNode.value="42";//Type"string"isnotassignabletotype

Page 151: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

"number"

numberNode.left=stringNode;//TypeNode<string>isnotassignableto

typeNode<number>

Intheprecedingsnippet,wecreatedthreenodes:numberNode,stringNode,andanothernodeofthetypeNode<number>,assigningitsvaluetotherightchildofnumberNode.NoticethatsincenumberNodeisofthetypeNode<number>,wecansetitsvalueto42,butwecan’tusethestring"42".Thesameisapplicabletoitsleftchild.Inthedefinition,we’veexplicitlydeclaredthatwewanttheleftandrightchildrentobeofthetypeNode<number>.ThismeansthatwecannotassignvaluesofthetypeNode<string>tothem;that’swhywegetthesecondcompile-timeerror.

Page 152: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsinggenericfunctionsAnothertypicaluseofgenericsisfordefiningfunctionsthatoperateoverasetoftypes.Forexample,wemaydefineanidentityfunctionthatacceptsanargumentoftypeTandreturnsit:

functionidentity<T>(arg:T){

returnarg;

}

However,insomecases,wemaywanttouseonlytheinstancesofthetypesthathavesomespecificproperties.Forachievingthis,wecanuseanextendedsyntaxthatallowsustodeclaresubtypesofthetypesthatshouldbethetypeparameters:

interfaceComparable{

compare(a:Comparable):number;

}

functionsort<TextendsComparable>(arr:Comparable[]):Comparable[]{

//…

}

Forexample,here,wedefinedaninterfacecalledComparable.Ithasasingleoperationcalledcompare.TheclassesthatimplementtheinterfaceComparableneedtoimplementtheoperationcompare.Whencompareiscalledwithagivenargument,itreturns1ifthetargetobjectisbiggerthanthepassedargument,0iftheyareequal,and-1ifthetargetobjectissmallerthanthepassedargument.

Page 153: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

HavingmultipletypeparametersTypeScriptallowsustousemultipletypeparameters:

classPair<K,V>{

key:K;

value:V;

}

Inthiscase,wecancreateaninstanceoftheclassPair<K,V>usingthefollowingsyntax:

letpair=newPair<string,number>();

pair.key="foo";

pair.value=42;

Page 154: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 155: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WritinglessverbosecodewithTypeScript’stypeinferenceStatictypinghasanumberofbenefits;however,itmakesuswriteamoreverbosecodebyaddingalltherequiredtypeannotations.

Insomecases,theTypeScript’scompilerisabletoguessthetypesofexpressionsinsideourcode,forinstance:

letanswer=42;

answer="42";//Type"string"isnotassignabletotype"number"

Intheprecedingexample,wedefinedavariableanswerandweassignedthevalue42toit.SinceTypeScriptisstaticallytypedandthetypeofavariablecannotchangeoncedeclared,thecompilerissmartenoughtoguessthatthetypeofanswerisnumber.

Ifwedon’tassignavaluetoavariablewithinitsdefinition,thecompilerwillsetitstypetoany:

letanswer;

answer=42;

answer="42";

Theprecedingsnippetwillcompilewithoutanycompile-timeerrors.

Page 156: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

BestcommontypeSometimes,thetypeinferencecouldbearesultofseveralexpressions.Suchisthecasewhenweassignaheterogeneousarraytoavariable:

letx=["42",42];

Inthiscase,thetypeofxwillbeany[].However,supposewehavethefollowing:

letx=[42,null,32];

Thetypeofxwillthenbenumber[],sincethetypeNumberisasubtypeofNull.

Page 157: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ContextualtypeinferenceContextualtypingoccurswhenthetypeofanexpressionisimpliedfromitslocation,forexample:

document.body.addEventListener("mousedown",e=>{

e.foo();//Property"foo"doesnotexistsonatype"MouseEvent"

},false);

Inthiscase,thetypeoftheargumentofthecallbackeisguessedbythecompilerbasedonthecontextinwhichitisused.ThecompilerunderstandswhatthetypeofeisbasedonthecallofaddEventListenerandtheargumentspassedtothemethod.Incasewewereusingakeyboardevent(keydown,forexample),TypeScriptwouldhavebeenawarethateisofthetypeKeyboardEvent.

TypeinferenceisamechanismthatallowsustowritelessverbosecodebytakingadvantageofthestaticanalysisperformedbyTypeScript.Basedonthecontext,TypeScript’scompilerisabletoguessthetypeofagivenexpressionwithoutexplicitdefinition.

Page 158: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 159: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingambienttypedefinitionsAlthoughstatictypingisamazing,mostofthefrontendlibrariesweusearebuiltwithJavaScript,whichisdynamicallytyped.Sincewe’dwanttouseTypeScriptinAngular2,nothavingcompile-typinginthecodethatusesexternallibrariesisabigissue;itpreventsusfromtakingadvantageofthecompile-timetype-checking.

TypeScriptwasbuiltkeepingthesepointsinmind.InordertoallowtheTypeScriptcompilertotakecareofwhatitdoesbest,wecanusetheso-calledambienttypedefinitions.TheyallowustoprovideexternaltypedefinitionsoftheexistingJavaScriptlibraries.Thisway,theyprovidehintstothecompiler.

Page 160: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingpredefinedambienttypedefinitionsFortunately,wedon’thavetocreateambienttypedefinitionsforallJavaScriptlibrariesandframeworksweuse.Thecommunityand/ortheauthorsoftheselibrarieshavealreadypublishedsuchdefinitionsonline;thebiggestrepositoryresidesat:https://github.com/DefinitelyTyped/DefinitelyTyped.There’salsoatoolformanagingthemcalledtypings.Wecaninstallitusingnpmbythefollowingcommand:

npminstall–gtypings

Theconfigurationoftypingsisdefinedinafilecalledtypings.jsonandallinstalledambienttypings,bydefault,willbeinthedirectory./typings.

Inordertocreatetypings.jsonfilewithbasicconfigurationuse:

typingsinit

Wecaninstallnewtypedefinitionusing:

typingsinstallangularjs--ambient

TheprecedingcommandwilldownloadthetypedefinitionsforAngularJS1.xandsavetheminbothbrowser/ambient/angular/angular.d.tsandmain/ambient/angular/angular.d.tsunderthetypingsdirectory.

NoteHavingbothmain/ambientandbrowser/ambientdirectoriesisduetopreventingtypecollisions.Forinstance,ifweuseTypeScriptinboththebackend/buildofourproject,anditsfrontendtherecouldbeintroducedduplicationsoftypedefinitionswhichwillleadtocompile-timeerrors.Byhavingtwodirectoriesfortheambienttypingsoftheindividualpartsoftheproject,wecanincludeonlyoneofthemusingrespectivelymain.d.tsandbrowser.d.ts.ForfurtherinformationontypingsyoucanvisittheofficialrepositoryoftheprojectonGitHubhttps://github.com/typings/typings.

Inordertodownloadatypedefinitionandaddentryforitinsidetypings.jsonyoucanuse:

typingsinstallangular--ambient--save

Afterrunningtheprecedingcommandyourtypings.jsonfileshouldlooksimilarto:

{

"dependencies":{},

"devDependencies":{},

"ambientDependencies":{

"angular":

"github:DefinitelyTyped/DefinitelyTyped/angularjs/angular.d.ts#1c4a34873c9e

70cce86edd0e61c559e43dfa5f75"

}

}

NowinordertouseAngularJS1.xwithTypeScriptcreateapp.tsandenterthefollowingcontent:

Page 161: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

///<referencepath="./typings/browser.d.ts"/>

varmodule=angular.module("module",[]);

module.controller("MainCtrl",

functionMainCtrl($scope:angular.IScope){

});

Tocompileapp.tsuse:

tscapp.ts

TheTypeScriptcompilewilloutputthecompiledcontentintoapp.js.InordertoaddextraautomationandinvoketheTypeScriptcompilereachtimeyouchangeanyofthefilesinyourproject,youcanuseataskrunnerlikegulporgrunt,orpassthe-woptiontotsc.

NoteSinceusingthereferenceelementforincludingtypedefinitionsisconsideredbadpracticewecanuseatsconfig.jsonfileinstead.Therewecanconfigurewhichdirectoriesneedtobeincludedinthecompilationprocessbytsc.Formoreinformationvisithttps://github.com/Microsoft/TypeScript/wiki/tsconfig.json.

Page 162: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

CustomambienttypedefinitionsTounderstandhoweverythingworkstogether,let’stakealookatanexample.SupposewehavethefollowinginterfaceofaJavaScriptlibrary:

varDOM={

//Returnsasetofelementswhichmatchthepassedselector

selectElements:function(selector){

//…

},

hide:function(element){

//…

},

show:function(element){

//…

}

};

WehaveanobjectliteralassignedtoavariablecalledDOM.Theobjecthasthefollowingmethods:

selectElements:AcceptsasingleargumentwithtypestringandreturnsasetofDOMelements.hide:AcceptsaDOMnodeasanargumentandreturnsnothing.show:AcceptsaDOMnodeasanargumentandreturnsnothing.

InTypeScript,theprecedingdefinitionwouldlookasfollows:

varDOM={

//Returnsasetofelementswhichmatchthepassedselector

selectElements:function(selector:string):HTMLElement[]{

return[];

},

hide:function(element:HTMLElement):void{

element.hidden=true;

},

show:function(element:HTMLElement):void{

element.hidden=false;

}

};

Thismeansthatwecandefineourlibrary’sinterfaceasfollows:

interfaceLibraryInterface{

selectElements(selector:string):HTMLElement[]

hide(element:HTMLElement):void

show(element:HTMLElement):void

}

Page 163: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Definingts.dfilesAfterwehavetheinterfaceofourlibrary,itwillbeeasytocreatetheambienttypedefinition;wejusthavetocreateafilewithanextensionts.dcalleddomandenterthefollowingcontent:

//inside"dom.d.ts"

interfaceDOMLibraryInterface{

selectElements(selector:string):HTMLElement[]

hide(element:HTMLElement):void

show(element:HTMLElement):void

}

declarevarDOM:DOMLibraryInterface;

Intheprecedingsnippet,wedefinedtheinterfacecalledDOMLibraryInterfaceanddeclaredthevariableDOMofthetypeDOMLibraryInterface.

TheonlythingleftbeforebeingabletoexploitstatictypingwithourJavaScriptlibraryisincludingtheexternaltypedefinitioninthescriptfileswewanttouseourlibraryin.Wecandoitasfollows:

///<referencepath="dom.d.ts"/>

Theprecedingsnippethintsthecompileronwheretofindtheambienttypedefinitions.

Page 164: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 165: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SummaryInthischapter,wepeekedattheTypeScriptlanguagethatisusedfortheimplementationofAngular2.AlthoughwecandevelopourAngular2applicationsusingECMAScript5,Google’srecommendationistouseTypeScriptinordertotakeadvantageofthestatictypingitprovides.

Whileexploringthelanguage,welookedatsomeofthecorefeaturesofES2015andES2016.WeexplainedtheES2015andES2016classes,arrowfunctions,blockscopevariabledefinitions,destructuring,andmodules.SinceAngular2takesadvantageoftheES2016decoratorsandmoreaccuratelytheirextensioninTypeScript,asectionwasdedicatedtothem.

Afterthis,wetookalookathowwecantakeadvantageofstatictypingbyusingexplicittypedefinitions.Wedescribedsomeofthebuilt-intypesinTypeScriptandhowwecandefineclassesinthelanguagebyspecifyingaccessmodifiersfortheirmembers.Ournextstopwastheinterfaces.WeendedouradventuresinTypeScriptbyexplainingthetypeparametersandtheambienttypedefinitions.

Inthenextchapter,wearegoingtostartexploringAngular2indepthbyusingtheframework’scomponentsanddirectives.

Page 166: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 167: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Chapter4.GettingStartedwithAngular2ComponentsandDirectivesBythispoint,you’realreadyfamiliarwiththecorebuildingblocksthatAngular2providesforthedevelopmentofsingle-pageapplicationsandtherelationsbetweenthem.However,we’vetouchedonlythesurfacebyintroducingthegeneralideabehindAngular’sconceptsandthebasicsyntaxusedfortheirdefinition.Inthischapter,we’lltakeadeepdiveintoAngular2’scomponentsanddirectives.

Inthefollowingsections,wewillcoverthesetopics:

EnforcedseparationofconcernsofthebuildingblocksthatAngular2providesfordevelopingapplications.TheappropriateuseofdirectivesorcomponentswheninteractingwiththeDOM.Built-indirectivesanddevelopingcustomones.Anin-depthlookatcomponentsandtheirtemplates.Contentprojection.Viewchildrenversuscontentchildren.Thecomponent’slifecycle.Usingtemplatereferences.ConfiguringAngular’schangedetection.

Page 168: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TheHelloworld!applicationinAngular2Now,let’sbuildourfirst“Helloworld!”appinAngular2!Inordertogeteverythingupandrunningaseasyandquicklyaspossible,forourfirstapplication,wewillusetheECMAScript5syntaxwiththetranspiledbundleofAngular2.First,createtheindex.htmlfilewiththefollowingcontent:

<!--ch4/es5/hello-world/index.html-->

<!DOCTYPEhtml>

<htmllang="en">

<head>

<metacharset="UTF-8">

<title></title>

</head>

<body>

<scriptsrc="https://code.angularjs.org/2.0.0-beta.9/angular2-

polyfills.min.js"></script>

<scriptsrc="https://code.angularjs.org/2.0.0-beta.9/Rx.umd.min.js">

</script>

<scriptsrc="https://code.angularjs.org/2.0.0-beta.9/angular2-

all.umd.min.js"></script>

<scriptsrc="./app.js"></script>

</body>

</html>

TheprecedingHTMLfiledefinesthebasicstructureofourpage.Justbeforeclosingthebodytag,wehavereferencestofourscriptfiles:thepolyfillsrequiredbytheframework(includingES2015shim,zone.js,andothers),RxJS,theES5bundleofAngular2,andthefilethatcontainstheapplicationwe’regoingtobuild.

NoteRxJSisusedbyAngular’scoreinordertoallowustoempowerthereactiveprogrammingparadigminourapplications.Inthefollowingcontent,wewilltakeonlyashallowlookathowwecantakeadvantageofobservables.Forfurtherinformation,youcanvisittheRxJSGitHubrepositoryathttps://github.com/Reactive-Extensions/RxJS.

Inthesamedirectorywhereyourindex.htmlresides,createafilecalledapp.jsandenterthefollowingcontentinsideit:

//ch4/es5/hello-world/app.js

varApp=ng.core.Component({

selector:'app',

template:'<h1>Hello{{target}}!</h1>'

})

.Class({

constructor:function(){

this.target='world';

}

});

Page 169: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ng.platform.browser.bootstrap(App);

Intheprecedingsnippet,wedefineacomponentcalledAppwithanappselector.Thisselectorwillmatchalltheappelementsinsideourtemplatesthatareinthescopeoftheapplication.Thecomponenthasthefollowingtemplate:

'<h1>Hello{{target}}!</h1>'

ThissyntaxshouldalreadybefamiliartoyoufromAngularJS1.x.Whencompiledinthecontextofthegivencomponent,theprecedingsnippetwillinterpolatethetemplatewiththeresultoftheexpressioninsidethecurlybrackets.Inourcase,theexpressionissimplythetargetvariable.

ToClass,wepassanobjectliteral,whichhasasinglemethodcalledconstructor.ThisDSLprovidesanalternativewaytodefineclassesinECMAScript5.Inthebodyoftheconstructorfunction,weaddapropertycalledtargetwithavalueofthe"world"string.Inthelastlineofthesnippet,weinvokethebootstrapmethodinordertoinitializeourapplicationwithAppasarootcomponent.

Notethatbootstrapislocatedunderng.platform.browser.Thisisduetothefactthattheframeworkisbuiltfordifferentplatformsinmind,suchasabrowser,NativeScript,andsoon.Byplacingthebootstrapmethodsusedbythedifferentplatformsunderaseparatenamespace,Angular2canimplementdifferentlogictoinitializetheapplicationandalsoincludedifferentsetsofprovidersanddirectivesthatareplatformspecific.

Now,ifyouopenindex.htmlwithyourbrowser,youshouldseesomeerrors,asshowninthefollowingscreenshot:

Thishappenedbecausewemissedsomethingquiteimportant.Wedidn’tusetherootcomponentanywhereinsideindex.html.Inordertofinishtheapplication,addthefollowingHTMLelementaftertheopentagofthebodyelement:

<app></app>

Now,youcanrefreshyourbrowsertoseethefollowingresult:

Page 170: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

NoteUsingTypeScript

AlthoughwealreadyhaveanAngular2applicationrunning,wecandomuchbetter!Wedidn’tuseanypackagemanagerormoduleloader.WespentallofChapter3,TypeScriptCrashCourse,talkingaboutTypeScript;however,wedidn’twriteasinglelineofitintheprecedingapplication.AlthoughitisnotrequiredthatyouuseTypeScriptwithAngular2,it’smuchconvenienttotakeadvantageofallthebonusesthatstatictypingprovides.

Page 171: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 172: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SettingupourenvironmentThecoreteamofAngulardevelopedabrandnewCLItoolforAngular2,whichallowsustobootstrapourapplicationswithafewcommands.Althoughwearegoingtointroduceitinthelastchapter,bythen,inordertoboostourlearningexperience,wearegoingtousethecodelocatedathttps://github.com/mgechev/switching-to-angular2.ItincludesalltheexamplesinthisbookandallowsustoquicklybootstrapourAngular2application(youcanknowmoreonhowtoquicklystartdevelopingwebapplicationswithAngular2inChapter5,DependencyInjectioninAngular2.).Ithasalltherequireddependenciesdeclaredinpackage.json,thedefinitionofbasicgulptasks,suchasthedevelopmentserver,thetranspilationofyourTypeScriptcodetoECMAScript5,live-reload,andsoon.Ourupcomingexamplesaregoingtobebasedonit.

Inordertosetuptheswitching-to-angular2project,you’llneedGit,Node.jsv5.x.x,andnpmupandrunningonyourcomputer.IfyouhaveadifferentversionoftheNode.jsinstalled,Irecommendthatyoutakealookatnvm(theNode.jsversionmanager,whichisavailableathttps://www.npmjs.com/package/nvm)orn(https://www.npmjs.com/package/n).Usingthesetools,you’llbeabletohavemultipleversionsofNode.jsonyourmachineandswitchbetweenthemwithasinglecommandviathecommandline.

Page 173: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

InstallingourprojectrepositoryLet’sstartbysettinguptheswitching-to-angular2project.Openyourterminalandenterthefollowingcommands:

#Willclonetherepositoryandsaveittodirectorycalled

#switching-to-angular2

gitclonehttps://github.com/mgechev/switching-to-angular2.git

cdswitching-to-angular2

npminstall

Thefirstlinewillclonetheswitching-to-angular2projectintoadirectorycalledswitching-to-angular2.

Thelaststepbeforebeingabletoruntheseedprojectistoinstallalltherequireddependenciesusingnpm.ThisstepmaytakeawhiledependingonyourInternetconnection,sobepatientanddonotinterruptit.Ifyouencounteranyproblems,donothesitatetoraisetheissuesathttps://github.com/mgechev/switching-to-angular2/issues.

Thelaststepleftistostartthedevelopmentserver:

npmstart

Whentheprocessofthetranspilationiscompleted,yourbrowserwillautomaticallyopenwiththisURL:http://localhost:5555/dist/dev.Youshouldnowseeaviewsimilartowhatisshowninthefollowingscreenshot:

Page 174: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 175: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

PlayingwithAngular2andTypeScriptNow,let’splayaroundwiththefileswealreadyhave!Navigatetotheapp/ch4/ts/hello-worlddirectoryinsideswitching-to-angular2.Then,openapp.tsandreplaceitscontentwiththefollowingsnippet:

//ch4/ts/hello-world/app.ts

import{Component}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

@Component({

selector:'app',

templateUrl:'./app.html'

})

classApp{

target:string;

constructor(){

this.target='world';

}

}

bootstrap(App);

Let’stakealookatthecodelinebyline:

import{Component}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

Initially,weimportthe@Componentdecoratorfromtheangular2/coremoduleandthebootstrapfunctionfromangular2/platform/browser.Later,[email protected]@Componentdecorator,wepassalmostthesameobjectliteralthatweusedintheECMAScript5versionoftheapplication,andthisway,wedefinetheCSSselectorforthecomponent.

Asanextstep,wedefinetheviewofthecomponent.However,notethatinthiscase,weusetemplateUrlinsteadofsimplyinliningthecomponent’stemplate.

Openapp.htmlandreplacethefile’scontentwith<h1>Hello{{target}}!</h1>.Thecontentofapp.htmlshouldbethesameastheinlinedtemplateweusedpreviously.Sincewecanuseatemplatebybothinliningit(withtemplate)andsettingitsURL(templateUrl),thecomponent’sAPIisquitesimilartotheAngularJS1.xdirectivesAPI.

Inthelastlineofthesnippet,webootstraptheapplicationbyprovidingtherootcomponent.

Page 176: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DiggingintotheindexNow,let’stakealookatindex.htmlinordertogetasenseofwhatgoesonwhenwestarttheapplication:

<!--ch4/ts/hello-world/index.html-->

<!DOCTYPEhtml>

<htmllang="en">

<head>

<metacharset="utf-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<title><%=TITLE%></title>

<metaname="description"content="">

<metaname="viewport"content="width=device-width,initial-scale=1">

<!--inject:css-->

<!--endinject-->

</head>

<body>

<app>Loading…</app>

<!--inject:js-->

<!--endinject-->

<%=INIT%>

</body>

</html>

Notethatinsidethebodyofthepage,weusetheappelementwiththecontentofthetextnode,"Loading…",inside.The"Loading…"labelwillbevisibleuntiltheapplicationgetsbootstrappedandthemaincomponentgetsrendered.

NoteTherearetemplateplaceholders<%=INIT%>and<--inject:js…thatinjectcontentthatisspecifictoindividualdemos.TheyarenotAngularspecificbutinsteadaimtopreventcodeduplicationsinthecodesamplesattachedtothebookbecauseofthesharedstructurebetweenthem.InordertoseehowthisspecificHTMLfilehasbeentransformed,open/dist/dev/ch4/ts/hello-world/index.html.

Page 177: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 178: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingAngular2directivesWealreadybuiltoursimple“Helloworld!”app.Now,let’sstartbuildingsomethingthatisclosertoareal-lifeapplication.Bytheendofthissection,we’llhaveasimpleapplicationthatlistsanumberofitemsweneedtodoandgreetsusattheheaderofthepage.

Let’sstartbydevelopingourappcomponent.Thetwomodificationsfromthepreviousexamplethatweneedtomakearetorenamethetargetpropertytonameandaddalistoftodostothecomponent’scontrollerdefinition:

//ch4/ts/ng-for/detailed-syntax/app.ts

import{Component}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

@Component({

selector:'app',

templateUrl:'./app.html',

})

classApp{

todos:string[];

name:string;

constructor(){

this.name='John';

this.todos=['Buymilk','Savetheworld'];

}

}

bootstrap(App);

Theonlythingleftistochangethetemplateinordertoconsumetheprovideddata.We’realreadyfamiliarwiththeng-repeatdirectivefromAngularJS1.x.Itallowsustoloopalistofitemsusingamicrosyntax,whichislaterinterpretedbyAngularJS1.x.However,thedirectivedoesn’tcarryenoughsemantics,soitishardtobuildtoolsthatperformstaticcodeanalysisandhelpusimproveourdevelopmentexperience.Sincetheng-repeatdirectiveisquiteuseful,Angular2tooktheideaandimproveditfurtherinordertoallowmoresophisticatedtoolingbyintroducingfurthersemanticsontopofit.ItallowsbetterstaticcodeanalysistobeperformedbyIDEsandtexteditors.Suchsupportwillpreventusfrommakingtyposinthecodewewriteandallowustohavesmootherdevelopmentexperience.

Inapp.html,addthefollowingcontent:

<!--ch4/ts/ng-for/detailed-syntax/app.html-->

<h1>Hello{{name}}!</h1>

<p>

Here'salistofthethingsyouneedtodo:

</p>

<ul>

<templatengForvar-todo[ngForOf]="todos">

<li>{{todo}}</li>

</template>

Page 179: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

</ul>

NoteThetemplateelementisaplacewherewecanholdmarkupandmakesurethatitwon’tberenderedbythebrowser.Thisisquiteusefulifweneedtoembedthetemplatesofourapplicationdirectlyintothemarkupofthepageandletthetemplateenginewe’reusingtoprocessthemlater.Inthecurrentexample,thismeansthatiftheAngular2DOMcompilerdoesn’tprocesstheDOMtree,allwe’regoingtoseeonthescreenaretheh1,pelementsandtheulelementwithoutanylistitems.

Now,afteryourefreshyourbrowser,youshouldseethefollowingresult:

Sofar,sogood!Theonlynewthingsleftintheprecedingsnippetsaretheattributesofthetemplateelementthatwe’renotfamiliarwith,suchasngFor,var-todo,and[ngForOf].Let’stakealookatthem.

Page 180: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ThengFordirectiveThengFordirectiveisadirectivethatallowsustoloopoveracollectionofitemsanddoesexactlywhatng-repeatdoesinAngularJS1.x,butitbringssomeextrasemantics.NotethatthengForOfattributeissurroundedbybrackets.Atfirst,thesebracketsmightseemlikeinvalidHTML.However,accordingtotheHTMLspecification,theiruseispermittedinattributenames.TheonlythingtheW3Cvalidatorisgoingtocomplainaboutisthefactthatthetemplateelementdoesn’townsuchattributes;however,browserswon’thaveproblemsprocessingthemarkup.

Thesemanticsbehindthesebracketsisthatthevalueoftheattributesurroundedbythemisanexpression,whichneedstobeevaluated.

Page 181: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 182: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ImprovedsemanticsofthedirectivessyntaxInChapter1,GettingStartedwithAngular2,wementionedtheopportunityforimprovedtoolinginAngular2.AbigissueinAngularJS1.xisthedifferentwaysinwhichwecanusedirectives.Thisrequiresanunderstandingoftheattributevalues,whichcanbeliterals,expressions,callbacks,oramicrosyntax.Angular2eliminatesthisproblembyintroducingafewsimpleconventionsthatarebuiltintotheframework:

propertyName="value"

[propertyName]="expression"

(eventName)="handler()"

Inthefirstline,thepropertyNameattributeacceptsastringliteralasavalue.Angularwillnotprocesstheattribute’svalueanyfurther;itwilluseitthewayitissetinthetemplate.

Thesecondsyntax,[propertyName]="expression",givesahinttoAngular2thatthevalueoftheattributesshouldbehandledasanexpression.WhenAngular2findsanattributesurroundedbybrackets,itwillinterprettheexpressioninthecontextofthecomponentassociatedtothetemplate.Inshort,ifwewanttosetanon-stringvalueorresultofanexpressionasvalueofgivenpropertyweneedtousethissyntax.

Thelastexampleshowshowwecanbindtoevents.Thesemanticsbehind(eventName)="handler()"isthatwewanttohandlealleventscalledeventNamethataretriggeredbythegivencomponentwiththehandler()expression.

We’regoingtodiscussmoreexampleslaterinthischapter.

NoteAngularprovidesalternativecanonicalsyntax,whichallowsustodefinethebindingsoftheelementswithoutusingbrackets.Forinstance,thepropertybindingcanbeexpressedusingthefollowingcode:

<input[value]="foo">

Itcanalsobeexpressedusingthis:

<inputbind-value="foo">

Similarly,wecanexpresstheeventbindingswiththefollowingcode:

<button(click)="handle()">Clickme</button>

Theycanalsobeexpressedusingthis:

<buttonon-click="handle()">Clickme</button>

Page 183: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DeclaringvariablesinsideatemplateThelastthingleftfromtheprecedingtemplateisthevar-todoattribute.WhatwearetellingAngularusingthissyntaxisthatwewanttodeclareanewvariablecalledtodoandbindittotheindividualitemsfromthecollectionwegetfromtheevaluationoftheexpressionsetasavalueof[ngForOf].

Page 184: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingsyntaxsugarintemplatesAlthoughthetemplatesyntaxisawesomeandprovidesmuchmoremeaningofthecodetotheIDEsortexteditorsweuse,itisquiteverbose.Angular2providesanalternativesyntax,whichwillbedesugaredtotheoneshowninthepreceding.Insteadofusingvar-todo,forexample,wecanuse#todo,whichhasthesamesemantics.

ThereareafewAngular2directivesthatrequiretheusageofatemplateelement,forexample,ngForOf,ngIf,andngSwitch.Sincesuchdirectivesareusedoften,there’sanalternativesyntaxforthem.Insteadoftypingdowntheentiretemplateelementexplicitly,wecansimplyprefixthedirectivewith*.ThiswillallowustoturnourngForOfdirectivesyntaxusageintothefollowing:

<!--ch4/ts/ng-for/syntax-sugar/app.html-->

<ul>

<li*ngFor="#todooftodos">{{todo}}</li>

</ul>

Later,thistemplatewillbedesugaredbyAngular2tothemoreverbosesyntaxdescribedearlier.Sincethelessverbosesyntaxiseasiertoreadandwrite,itsuseisconsideredasbestpractice.

NoteThe*characterallowsyoutoremovethetemplateelementandputthedirectivedirectlyontherootofthetemplateelement(intheprecedingexample,thelistitem,li).

Page 185: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 186: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningAngular2directivesNowthatwe’vebuiltasimpleAngular2component,let’scontinueourjourneybyunderstandingtheAngular2directives.

UsingAngular2directives,wecanapplydifferentbehavioralorstructuralchangesovertheDOM.Inthisexample,we’regoingtobuildasimpletooltipdirective.

Incontrasttocomponents,directivesdonothaveviewsandtemplates,respectively.AnothercoredifferencebetweenthesetwoconceptsisthatthegivenHTMLelementmayhaveonlyasinglecomponentbutmultipledirectivesonit.Inotherwords,directivesaugmenttheelementscomparedtocomponentsthataretheactualelementsinourviews.

Angular’scoreteam’srecommendationistousedirectivesasattributes,prefixedwithanamespace.Keepingthisinmind,wewillusethetooltipdirectiveinthefollowingway:

<divsaTooltip="Helloworld!"></div>

Intheprecedingsnippet,weusethetooltipdirectiveoverthedivelement.Asanamespace,itsselectorusesthesastring.

NoteForsimplicity,intherestofthebookwemaynotprefixalltheselectorsofourcomponentsanddirectives.However,forproductionapplicationsfollowingbestpracticesisessential.YoucanfindanAngular2styleguidewhichpointsoutsuchpracticesathttps://github.com/mgechev/angular2-style-guide.

Beforeimplementingourtooltip,weneedtoimportacoupleofthingsfromangular2/core.OpenanewTypeScriptfilecalledapp.tsandenterthefollowingcontent;we’llfilltheplaceholderslater:

import{Directive,ElementRef,HostListener…}from'angular2/core';

Intheprecedingline,weimportthefollowingdefinitions:

ElementRef:Thisallowsustoinjecttheelementreference(we’renotlimitedtotheDOMonly)tothehostelement.Inthesampleusageoftheprecedingtooltip,wegetanAngularwrapperofthedivelement,whichholdsthetooltipattribute.Directive:Thisdecoratorallowsustoaddthemetadatarequiredforthenewdirectiveswedefine.HostListener(eventname):Thisisamethoddecoratorthatacceptsaneventnameasanargument.Duringinitializationofthedirective,Angular2willaddthedecoratedmethodasaneventhandlerfortheeventnameeventofthehostelement.

Let’slookatourimplementation;thisiswhatthedirective’sdefinitionlookslike:

//ch4/ts/tooltip/app.ts

@Directive({

selector:'[saTooltip]'

})

Page 187: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

exportclassTooltip{

@Input()

saTooltip:string;

constructor(privateel:ElementRef,privateoverlay:Overlay){

this.overlay.attach(el.nativeElement);

}

@HostListener('mouseenter')

onMouseEnter(){

this.overlay.open(this.el,this.saTooltip);

}

@HostListener('mouseleave')

onMouseLeave(){

this.overlay.close();

}

}

Page 188: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Settingthedirective’sinputsIntheprecedingexample,wedeclareadirectivewiththesaTooltipselector.NotethatAngular’sHTMLcompileriscasesensitive,whichmeansthatitwilldistinguishthe[satooltip]and[saTooltip]selectors.Later,wewilldeclaretheinputofthedirectiveusingthe@InputdecoratoroverthesaTooltipproperty.Thesemanticsbehindthiscodeis:declareapropertycalledsaTooltipandbindittothevalueoftheresultthatwegotfromtheevaluationoftheexpressionpassedtothesaTooltipattribute.

The@Inputdecoratoracceptsasingleargument—thenameoftheattributewewanttobindto.Incasewedon’tpassanargument,Angularwillcreateabindingbetweentheattributewiththesamenameasthepropertyitself.Wewillexplaintheconceptofinputandoutputindetaillaterinthischapter.

Page 189: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Understandingthedirective’sconstructorTheconstructordeclarestwoprivateproperties:eloftheElementReftypeandoverlayoftheOverlaytype.TheOverlayclassimplementslogictomanagethetooltips’overlaysandisgoingtobeinjectedusingtheDImechanismofAngular.Inordertodeclareitasavailableforinjection,weneedtodeclarethetop-levelcomponentinthefollowingway:

@Component({

selector:'app',

templateUrl:'./app.html',

providers:[Overlay],

//...

})

classApp{}

NoteWe’regoingtotakealookatthedependencyinjectionmechanismofAngular2inthenextchapter,wherewewillexplainthewayinwhichwecandeclarethedependenciesofourservices,directives,andcomponents.

TheimplementationoftheOverlayclassisnotimportantforthepurposeofthischapter.However,ifyou’reinterestedinit,youcanfindtheimplementationin:ch4/ts/tooltip/app.ts.

Page 190: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

BetterencapsulationofdirectivesInordertomakethetooltipdirectiveavailabletotheAngular’scompiler,weneedtoexplicitlydeclarewhereweintendtouseit.Forinstance,takealookattheAppclassatch4/ts/tooltip/app.ts;there,youcannoticethefollowing:

@Component({

selector:'app',

templateUrl:'./app.html',

providers:[Overlay],

directives:[Tooltip]

})

classApp{}

Tothe@Componentdecorator,wepassanobjectliteralthathasthedirectivesproperty.Thispropertycontainsalistofallthedirectivesthatshouldbeavailableintheentirecomponentsubtreewiththerootofthegivencomponent.

Atfirst,itmightseemannoyingthatyoushouldexplicitlydeclareallthedirectivesthatyourcomponentuses;however,thisenforcesbetterencapsulation.InAngularJS1.x,alldirectivesareinaglobalnamespace.Thismeansthatallthedirectivesdefinedintheapplicationareaccessibleinallthetemplates.Thisbringsinsomeproblems,forexample,namecollision.Inordertodealwiththisissue,we’veintroducednamingconventions,forinstance,the“ng-”prefixofallthedirectivesdefinedbyAngularJS1.xand“ui-”foralldirectivescomingwiththeAngularUI.

Thisway,byexplicitlydeclaringallthedirectives,thegivencomponentusesinAngular2,wecreateanamespacespecifictotheindividualcomponents’subtrees(thatis,thedirectiveswillbevisibletothegivenrootcomponentandallofitssuccessorcomponents).Preventingnamecollisionsisnottheonlybenefitweget;italsohelpsuswithbettersemanticsofthecodethatweproduce,sincewe’realwaysawareofthedirectivesaccessiblebythegivencomponent.Wecanfindalltheaccessibledirectivesofthegivencomponentbyfollowingthepathfromthecomponenttothetopofthecomponenttreeandtakingtheunionofallthevaluesofdirectivesarrayssetinthe@Componentdecorators.Giventhatcomponentsareextendedfromdirectives,weneedtoexplicitlydeclarealltheusedcomponentsaswell.

SinceAngular2definesasetofbuilt-indirectives,thebootstrapmethodpassestheminasimilarwayinordertomakethemavailableintheentireapplicationinordertopreventusfromcodeduplications.ThislistofpredefineddirectivesincludesNgClass,NgFor,NgIf,NgStyle,NgSwitch,NgSwitchWhen,andNgSwitchDefault.Theirnamesarequiteself-explanatory;we’lltakealookathowwecanusesomeofthemlaterinthischapter.

Page 191: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 192: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingAngular2’sbuilt-indirectivesNow,let’sbuildasimpleto-doapplicationinordertodemonstratethesyntaxtodefinecomponentsfurther!

Ourto-doitemswillhavethefollowingformat:

interfaceTodo{

completed:boolean;

label:string;

}

Let’sstartbyimportingeverythingwearegoingtoneed:

import{Component,ViewEncapsulation}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

Now,let’sdeclarethecomponentandthemetadataassociatedwithit:

@Component({

selector:'todo-app',

templateUrl:'./app.html',

styles:[

`ulli{

list-style:none;

}

.completed{

text-decoration:line-through;

}`

],

encapsulation:ViewEncapsulation.Emulated

})

Here,wespecifythattheselectoroftheTodocomponentwillbethetodo-appelement.Later,weaddthetemplateURL,whichpointstotheapp.htmlfile.Afterthat,weusethestylesproperty;thisisthefirsttimeweencounterit.Aswecanguessfromitsname,itisusedtosetthestylesofthecomponent.

Page 193: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 194: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Introducingthecomponent’sviewencapsulationAsweknow,Angular2isinspiredfromWebComponents,whosecorefeatureistheshadowDOM.TheshadowDOMallowsustoencapsulatethestylesofourWebComponentswithoutallowingthemtoleakoutsidethecomponent’sscope.Angular2providesthisfeature.IfwewantAngular’srenderertousetheshadowDOM,wecanuseViewEncapsulation.Native.However,theshadowDOMisnotsupportedbyallbrowsers;ifwewanttohavethesamelevelofencapsulationwithoutusingtheshadowDOM,wecanuseViewEncapsulation.Emulated.Ifwedon’twanttohaveanyencapsulationatall,wecanuseViewEncapsulation.None.Bydefault,therendererusesencapsulationofthetypeEmulated.

Page 195: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 196: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Implementingthecomponent’scontrollersNow,let’scontinuewiththeimplementationoftheapplication:

//ch4/ts/todo-app/app.ts

classTodoCtrl{

todos:Todo[]=[{

label:'Buymilk',

completed:false

},{

label:'Savetheworld',

completed:false

}];

name:string='John';

addTodo(label){…}

removeTodo(idx){…}

toggleCompletion(idx){…}

}

HereispartoftheimplementationofthecontrollerassociatedwiththetemplateoftheTodoapplication.

Insidetheclassdeclaration,weinitializedthetodospropertytoanarraywithtwotodoitems:

{

label:'Buymilk',

completed:false

},{

label:'Savetheworld',

completed:false

}

Now,let’supdatethetemplateandrendertheseitems!Here’showthisisdone:

<ul>

<li*ngFor="#todooftodos;varindex=index"

[class.completed]="todo.completed">

<inputtype="checkbox"[checked]="todo.completed"

(change)="toggleCompletion(index)">

{{todo.label}}

</li>

</ul>

Intheprecedingtemplate,weloopedallthetodoitemsinsidethetodospropertyofthecontroller.Foreachtodoitem,wecreatedacheckboxthatcantoggletheitem’scompletionstatus;wealsorenderedthetodoitem’slabelwiththeinterpolationdirective.Here,wecannoticethesyntaxthatwasexplainedearlier:

Webindtothechangeeventofthecheckboxusing(change)="statement".Webindtothepropertyofthetodoitemusing[checked]="expr".

Inordertohavealineacrossthecompletedtodoitems,webindtotheclass.completedpropertyoftheelement.Sincewewanttoapplythecompletedclasstoallthecompleted

Page 197: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

to-doitems,weuse[class.completed]="todo.completed".Thisway,wedeclarethatwewanttoapplythecompletedclassdependingonthevalueofthetodo.completedexpression.Hereishowourapplicationlooksnow:

NoteSimilartotheclassbindingsyntax,Angularallowsustobindtotheelement’sstylesandattributes.Forinstance,wecanbindtothetdelement’scolspanattributeusingthefollowinglineofcode:

<td[attr.colspan]="colspanCount"></td>

Inthesameway,wecanbindtoanystylepropertyusingthislineofcode:

<div[style.backgroundImage]="expression"></td>

Page 198: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 199: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

HandlinguseractionsSofar,sogood!Now,let’simplementthetoggleCompletionmethod.Thismethodacceptstheindexoftheto-doitemasasingleargument:

toggleCompletion(idx){

lettodo=this.todos[idx];

todo.completed=!todo.completed;

}

IntoggleCompletion,wesimplytogglethecompletedBooleanvalueassociatedwiththecurrentto-doitem,whichisspecifiedbytheindexpassedasanargumenttothemethod.

Now,let’saddatextinputtoaddthenewto-doitems:

<p>

Addanewtodo:

<input#newtodotype="text">

<button(click)="addTodo(newtodo.value);newtodo.value=''">

Add

</button>

</p>

Theinputheredefinesanewidentifiercallednewtodo.Wecanreferencetheinputusingthenewtodoidentifierinsidethetemplate.Oncetheuserclicksonthebutton,theaddTodomethoddefinedinthecontrollerwillbeinvokedwiththevalueofthenewtodoinputasanargument.Insidethestatementthatispassedtothe(click)attribute,wealsoresetthevalueofthenewtodoinputbysettingittotheemptystring.

NoteNotethatdirectlymanipulatingDOMelementsisnotconsideredasbestpracticesinceitwillpreventourcomponentfromrunningproperlyoutsidethebrowserenvironment.WewillexplainhowwecanmigratethisapplicationtoWebWorkersinChapter8,DevelopmentExperienceandServer-SideRendering.

Now,let’sdefinetheaddTodomethod:

addTodo(label){

this.todos.push({

label,

completed:false

});

}

Insideit,wecreateanewto-doitemusingtheobjectliteralsyntax.

Theonlythingleftoutofourapplicationistoimplementremovalofexistingto-doitems.Sinceitisquitesimilartothefunctionalityusedtotogglethecompletionoftheto-doitems,I’llleaveitsimplementationasasimpleexerciseforthereader.

Page 200: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Usingadirectives’inputsandoutputsByrefactoringourtodoapplication,wearegoingtodemonstratehowwecantakeadvantageofthedirectives’inputsandoutputs:

Wecanthinkoftheinputsasproperties(orevenarguments)thatthegivendirectiveaccepts.Theoutputscouldbeconsideredaseventsthatittriggers.Whenweuseadirectiveprovidedbyathird-partylibrary,mostlywecareaboutisitsinputsandoutputsbecausetheydefineitsAPI.

Inputsreferstovaluesthatparameterizethedirective’sbehaviorand/orview.Ontheotherhand,outputsreferstoeventsthatthedirectivefireswhensomethingspecialhappens.

Page 201: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Findingoutdirectives’inputsandoutputsNow,let’sdivideourmonolithicto-doapplicationintoseparatecomponentsthatcommunicatewitheachother.Inthefollowingscreenshot,youcanseetheindividualcomponentsthatwhencomposedtogetherimplementthefunctionalityoftheapplication:

TheouterrectanglerepresentstheentireTodoapplication.Thefirstnestedrectanglecontainsthecomponentthatisresponsibleforenteringlabelsofthenewto-doitems,andtheonebelowitliststheindividualitemsthatarestoredintherootcomponent.

Havingsaidthis,wecandefinethesethreecomponentsasfollows:

TodoApp:Responsibleformaintainingthelistofto-doitems(addingnewitemsandtogglingthecompletionstatus).InputBox:Responsibleforenteringthelabelofthenewto-doitem.Ithasthefollowinginputsandoutputs:

Input:Aplaceholderforthetextboxandalabelforthesubmitbutton.Output:Itshouldemitthecontentoftheinputoncethesubmitbuttonisclicked.

TodoList:Thisisresponsibleforrenderingtheindividualto-doitems.Ithasthefollowinginputsandoutputs:

Input:Thelistofto-doitems.Output:Oncethecompletionstatusofanyoftheto-doitemschanges,thecomponentshouldemitthechange.

Now,let’sbeginwiththeimplementation!

Page 202: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Definingthecomponent’sinputsandoutputsLet’suseabottom-upapproachandstartwiththeInputBoxcomponent.Beforethat,weneedacoupleofimportsfromAngular’sangular2/corepackage:

import{

Component,

Input,

Output,

EventEmitter

}from'angular2/core';

Intheprecedingcode,weimportedthe@Component,@Input,[email protected],@Inputand@Outputareusedfordeclaringthedirective’sinputsandoutputs.EventEmitterisagenericclass(thatis,acceptingtypeparameter)whichcombinedwiththe@Outputdecoratorhelpsusemitoutputs.

Asthenextstep,let’stakealookattheInputBoxcomponent’sdeclaration:

//ch4/ts/inputs-outputs/app.ts

@Component({

selector:'text-input',

template:`

<input#todoInput[placeholder]="inputPlaceholder">

<button(click)="emitText(todoInput.value);

todoInput.value='';">

{{buttonLabel}}

</button>

`

})

classInputBox{...}

Notethatinthetemplate,wedeclareatextinputcalledtodoInputandsetitsplaceholderpropertytothevaluethatwegotfromtheevaluationoftheinputPlaceholderexpression.ThevalueoftheexpressionisthevalueoftheinputPlaceholderpropertydefinedinthecomponent’scontroller.Thisisthefirstinputthatweneedtodefine:

classInputBox{

@Input()inputPlaceholder:string;

...

}

Similarly,wedeclaretheotherinputofthebuttonLabelcomponent,whichweuseasavalueofthelabelofthebutton:

classInputBox{

@Input()inputPlaceholder:string;

@Input()buttonLabel:string;

...

}

Intheprecedingtemplate,webindtheclickeventofthebuttontothisexpression:emitText(todoInput.value);todoInput.value='';.TheemitTextmethodis

Page 203: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

supposedtobedefinedinthecomponent’scontroller;onceitisinvoked,itshouldemitthevalueofthetextinput.Hereishowwecanimplementthisbehavior:

classInputBox{

...

@Output()inputText=newEventEmitter<string>();

emitText(text:string){

this.inputText.emit(text);

}

}

Initially,wedeclareanoutputcalledinputText.Asitsvalue,wesetanewinstanceofthetypeEventEmitter<string>thatwecreate.

NoteNotethatalltheoutputsofallthecomponentsneedtobeinstancesofEventEmitter.

InsidetheemitTextmethod,weinvoketheemitmethodoftheinputTextinstancewiththeargumentofthevalueofthetextinput.

Now,let’sdefinetheTodoListcomponentinthesamefashion:

@Component(...)

classTodoList{

@Input()todos:Todo[];

@Output()toggle=newEventEmitter<Todo>();

toggleCompletion(index:number){

lettodo=this.todos[index];

this.toggle.emit(todo);

}

}

Sincethevalueoftheobjectliteralpassedtothe@Componentdecoratorisnotessentialforthepurposeofthissection,we’veomittedit.Thecompleteimplementationofthisexamplecouldbefoundatch4/ts/inputs-outputs/app.ts.Let’stakealookatthebodyoftheTodoListclass.Similarly,fortheInputBoxcomponent,wedefinethetodosinput.Wealsodefinethetoggleoutputbydeclaringthetoggleproperty,settingitsvaluetoanewinstanceofthetypeEventEmitter<Todo>anddecoratingitwiththe@Outputdecorator.

Page 204: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

PassinginputsandconsumingtheoutputsNow,let’scombinethecomponentswedefinedintheprecedingsectionandimplementourcompleteapplication!

ThelastcomponentweneedtotakealookatisTodoApp:

@Component({

selector:'todo-app',

directives:[TodoList,InputBox],

template:`

<h1>Hello{{name}}!</h1>

<p>

Addanewtodo:

<input-boxinputPlaceholder="Newtodo…"

buttonLabel="Add"

(inputText)="addTodo($event)">

</input-box>

</p>

<p>Here'sthelistofpendingtodoitems:</p>

<todo-list[todos]="todos"(toggle)="toggleCompletion($event)"></todo-

list>

`

})

classTodoApp{...}

Initially,wedefinetheTodoAppclassanddecorateitwiththe@Componentdecorator.Notethatinthelistofthedirectivesusedbythecomponent,weincludeInputBoxandTodoList.Themagicofhowthesecomponentscollaboratetogetherhappensinthetemplate:

<input-boxinputPlaceholder="Newtodo…"

buttonLabel="Add"

(inputText)="addTodo($event)">

</input-box>

First,weusetheInputBoxcomponentandpassvaluestotheinputs:inputPlaceholderandbuttonLabel.Notethatjustlikewesawearlier,ifwewanttopassanexpressionasavaluetoanyoftheseinputs,weneedtosurroundthemwithbrackets(thatis,[inputPlaceholder]="expression").Inthiscase,theexpressionwillbeevaluatedinthecontextofthecomponentthatownsthetemplate,anditwillbepassedasaninputtothecomponentthatownsthegivenproperty.

RightafterwepassthevalueforthebuttonLabelinput,weconsumetheinputTextoutputbysettingthevalueofthe(inputText)attributetotheaddTodo($event)expression.Thevalueof$eventwillequalthevaluewepassedtotheemitmethodoftheinputTextobjectinsidetheemitTextmethodofInputBox(incasewebindtoanativeevent,thevalueoftheeventobjectwillbethenativeeventobjectitself).

Inthesameway,wepasstheinputoftheTodoListcomponentandhandleitstoggleoutput.Now,let’sdefinethelogicbehindtheTodoAppcomponent:

Page 205: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

classTodoApp{

todos:Todo[]=[];

name:string='John';

addTodo(label:string){

this.todos.push({

label,

completed:false

});

}

toggleCompletion(todo:Todo){

todo.completed=!todo.completed;

}

}

IntheaddTodomethod,wesimplypushanewto-doitemtothetodosarray.TheimplementationoftoggleCompletionisevensimpler—wetogglethevalueofthecompletedflagthatispassedasanargumenttotheto-doitem.Now,wearefamiliarwiththebasicsofthecomponents’inputsandoutputs!

Page 206: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

EventbubblingInAngular,wehavethesamebubblingbehaviorwehaveintheDOM.Forinstance,ifwehavethefollowingtemplate:

<input-boxinputPlaceholder="Newtodo…"

buttonLabel="Add"

(click)="handleClick($event)"

(inputText)="addTodo($event)">

</input-box>

Thedeclarationofinput-boxlookslikethis:

<input#todoInput[placeholder]="inputPlaceholder">

<button(click)="emitText(todoInput.value);

todoInput.value='';">

{{buttonLabel}}

</button>

Oncetheuserclicksonthebuttondefinedwithinthetemplateoftheinput-boxcomponent,thehandleClick($event)expressionwillbeevaluated.

Further,thetargetpropertyofthefirstargumentofhandleClickwillbethebuttonitself,butthecurrentTargetpropertywillbetheinput-boxelement.

NoteNotethatunlikenativeevents,onestriggeredbyEventEmitterwillnotbubble.

Page 207: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

RenamingtheinputsandoutputsofadirectiveNow,wewillexplorehowwecanrenamethedirectives’inputsandoutputs!Let’ssupposethatwehavethefollowingdefinitionoftheTodoListcomponent:

classTodoList{

...

@Output()toggle=newEventEmitter<Todo>();

toggle(index:number){

...

}

}

Theoutputofthecomponentiscalledtoggle;themethodthathandleschangesinthecheckboxesresponsiblefortogglingcompletionoftheindividualto-doitemsiscalledtoggleaswell.ThiscodewillnotbecompiledasintheTodoListcontroller,wehavetwoidentifiersnamedinthesameway.Wehavetwooptionshere:wecaneitherrenamethemethodortheproperty.Ifwerenametheproperty,thiswillchangethenameofthecomponent’soutputaswell.So,thefollowinglineofcodewillnolongerwork:

<todo-list[toggle]="foobar($event)"...></todo-list>

Whatwecandoinsteadisrenamethetogglepropertyandexplicitlysetthenameoftheoutputusingthe@Outputdecorator:

classTodoList{

...

@Output('toggle')toggleEvent=newEventEmitter<Todo>();

toggle(index:number){

...

}

}

Thisway,wewillbeabletotriggerthetoggleoutputusingthetoggleEventproperty.

NoteNotethatsuchrenamescouldbeconfusingandarenotconsideredasbestpractices.Foracompletesetofbestpracticesvisithttps://github.com/mgechev/angular2-style-guide.

Similarly,wecanrenamecomponent’sinputsusingthefollowingcodesnippet:

classTodoList{

@Input('todos')todoList:Todo[];

@Output('toggle')toggleEvent=newEventEmitter<Todo>();

toggle(index:number){

...

}

}

Now,nomatterthatwerenamedtheinputandoutputpropertiesofTodoList,itstillhasthesamepublicinterface:

<todo-list[todos]="todos"

(toggle)="toggleCompletion($event)">

Page 208: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

</todo-list>

Page 209: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

AnalternativesyntaxtodefineinputsandoutputsThe@Inputand@Outputdecoratorsaresyntaxsugarforeasierdeclarationofthedirective’sinputsandoutputs.Theoriginalsyntaxforthispurposeisasfollows:

@Directive({

outputs:['outputName:outputAlias'],

inputs:['inputName:inputAlias']

})

classDir{

outputName=newEventEmitter();

}

Using@Inputand@Output,theprecedingsyntaxisequivalenttothis:

@Directive(...)

classDir{

@Output('outputAlias')outputName=newEventEmitter();

@Input('inputAlias')inputName;

}

Althoughbothhavethesamesemantics,accordingtothebestpractices,weshouldusethelatteronebecauseitiseasiertoreadandunderstand.

Page 210: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 211: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ExplainingAngular2’scontentprojectionContentprojectionisanimportantconceptwhendevelopinguserinterfaces.Itallowsustoprojectpiecesofcontentintodifferentplacesoftheuserinterfaceofourapplication.WebComponentssolvethisproblemwiththecontentelement.InAngularJS1.x,itisimplementedwiththeinfamoustransclusion.

Angular2isinspiredbymodernwebstandards,especiallyWebComponents,whichledtotheadoptionofsomeofthemethodsofcontentprojectionusedthere.Inthissection,we’lllookattheminthecontextofAngular2usingtheng-contentdirective.

Page 212: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

BasiccontentprojectioninAngular2Let’ssupposewe’rebuildingacomponentcalledfancy-button.ThiscomponentwillusethestandardHTMLbuttonelementandaddsomeextrabehaviortoit.Hereisthedefinitionofthefancy-buttoncomponent:

@Component({

selector:'fancy-button',

template:'<button>Clickme</button>'

})

classFancyButton{…}

Insideofthe@Componentdecorator,wesettheinlinetemplateofthecomponenttogetherwithitsselector.Now,wecanusethecomponentwiththefollowingmarkup:

<fancy-button></fancy-button>

Onthescreen,wearegoingtoseeastandardHTMLbuttonthathasalabelwiththecontentClickme.ThisisnotaveryflexiblewaytodefinereusableUIcomponents.Mostlikely,theusersofthefancybuttonwillneedtochangethecontentofthelabeltosomething,dependingontheirapplication.

InAngularJS1.x,wewereabletoachievethisresultwithng-transclude:

//AngularJS1.xexample

app.directive('fancyButton',function(){

return{

restrict:'E',

transclude:true,

template:'<button><ng-transclude></ng-transclude></button>'

};

});

InAngular2,wehavetheng-contentelement:

//ch4/ts/ng-content/app.ts

@Component({

selector:'fancy-button',

template:'<button><ng-content></ng-content></button>'

})

classFancyButton{/*Extrabehavior*/}

Now,wecanpasscustomcontenttothefancybuttonbyexecutingthis:

<fancy-button>Click<i>me</i>now!</fancy-button>

Asaresult,thecontentbetweentheopeningandtheclosingfancy-buttontagswillbeplacedwheretheng-contentdirectiveresides.

Page 213: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ProjectingmultiplecontentchunksAnothertypicalusecaseofcontentprojectioniswhenwepasscontenttoacustomAngular2componentorAngularJS1.xdirectiveandwewantdifferentpartsofthiscontenttobeprojectedtodifferentlocationsinthetemplate.

Forinstance,let’ssupposewehaveapanelcomponentthathasatitleandabody:

<panel>

<panel-title>Sampletitle</panel-title>

<panel-content>Content</panel-content>

</panel>

Andwehavethefollowingtemplateofourcomponent:

<divclass="panel">

<divclass="panel-title">

<!--Projectthecontentofpanel-titlehere-->

</div>

<divclass="panel-content">

<!--Projectthecontentofpanel-contenthere-->

</div>

</div>`

InAngularJS1.5,weareabletodothisusingmulti-slottransclusion,whichwasimplementedinordertoallowustohaveasmoothertransitiontoAngular2.Let’stakealookathowwecanproceedinAngular2inordertodefinesuchapanelcomponent:

//ch4/ts/ng-content/app.ts

@Component({

selector:'panel',

styles:[…],

template:`

<divclass="panel">

<divclass="panel-title">

<ng-contentselect="panel-title"></ng-content>

</div>

<divclass="panel-content">

<ng-contentselect="panel-content"></ng-content>

</div>

</div>`

})

classPanel{}

Wehavealreadydescribedtheselectorandstylesproperties,solet’stakealookatthecomponent’stemplate.Wehaveadivelementwiththepanelclass,whichwrapsthetwonesteddivelements,respectively:oneforthetitleofpanelandoneforthecontentofpanel.Inordertograbthecontentfromthepanel-titleelementandprojectitwherethetitleofthepanelissupposedtobeintherenderedpanel,weneedtousetheng-contentelementwiththeselectorattribute,whichhasthepanel-titlevalue.ThevalueoftheselectorattributeisaCSSselector,whichinthiscaseisgoingtomatchallthepanel-titleelementsthatresideinsidethetargetpanelelement.Afterthis,ng-contentwillgrabtheircontentandsetthemasitsowncontent.

Page 214: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

NestingcomponentsWe’vealreadybuiltafewsimpleapplicationsasacompositionofcomponentsanddirectives.Wesawthatcomponentsarebasicallydirectiveswithviews,sowecanimplementthembynesting/composingotherdirectivesandcomponents.Thefollowingfigureillustratesthiswithastructuraldiagram:

Thecompositioncouldbeachievedbynestingdirectivesandcomponentswithinthecomponents’templates,takingadvantageofthenestednatureoftheusedmarkup.Forinstance,let’ssaywehaveacomponentwiththesample-componentselector,whichhasthefollowingdefinition:

@Component({

selector:'sample-component',

template:'<view-child></view-child>'

})

classSample{}

Thetemplateofthesample-componentselectorhasasinglechildelementwiththetagnameview-child.

Ontheotherhand,wecanusethesample-componentselectorinsidethetemplateofanothercomponent,andsinceitcanbeusedasanelement,wecannestothercomponentsordirectivesinsideit:

<sample-component>

<content-child1></content-child1>

<content-child2></content-child2>

</sample-component>

Thisway,thesample-componentcomponenthastwodifferenttypesofsuccessors:

Thesuccessordefinedwithinitstemplate.Thesuccessorthatispassedasnestedelementsbetweenitsopeningandclosingtags.

Page 215: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

InthecontextofAngular2,thedirectchildrenelementsdefinedwithinthecomponent’stemplatearecalledviewchildrenandtheonesnestedbetweenitsopeningandclosingtagsarecalledcontentchildren.

Page 216: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingViewChildrenandContentChildrenLet’stakealookattheimplementationoftheTabscomponent,whichusesthefollowingstructure:

<tabs(changed)="tabChanged($event)">

<tab-title>Tab1</tab-title>

<tab-content>Content1</tab-content>

<tab-title>Tab2</tab-title>

<tab-content>Content2</tab-content>

</tabs>

Theprecedingstructureiscomposedofthreecomponents:

TheTabcomponent.TheTabTitlecomponent.TheTabContentcomponent.

Let’slookattheimplementationoftheTabTitlecomponent:

@Component({

selector:'tab-title',

styles:[…],

template:`

<divclass="tab-title"(click)="handleClick()">

<ng-content></ng-content>

</div>

`

})

classTabTitle{

tabSelected:EventEmitter<TabTitle>=

newEventEmitter<TabTitle>();

handleClick(){

this.tabSelected.emit(this);

}

}

There’snothingnewinthisimplementation.WedefineaTabTitlecomponent,whichhasasinglepropertycalledtabSelected.ItisofthetypeEventEmitterandwillbetriggeredoncetheuserclicksonthetabtitle.

Now,let’stakealookattheTabContentcomponent:

@Component({

selector:'tab-content',

styles:[…],

template:`

<divclass="tab-content"[hidden]="!isActive">

<ng-content></ng-content>

</div>

`

})

classTabContent{

isActive:boolean=false;

}

Page 217: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Thishasanevensimplerimplementation—allwedoisprojecttheDOMpassedtothetab-contentelementinsideng-contentandhideitoncethevalueoftheisActivepropertybecomesfalse.

TheinterestingpartoftheimplementationistheTabscomponentitself:

//ch4/ts/basic-tab-content-children/app.ts

@Component({

selector:'tabs',

styles:[…],

template:`

<divclass="tab">

<divclass="tab-nav">

<ng-contentselect="tab-title"></ng-content>

</div>

<ng-contentselect="tab-content"></ng-content>

</div>

`

})

classTabs{

@Output('changed')

tabChanged:EventEmitter<number>=newEventEmitter<number>();

@ContentChildren(TabTitle)

tabTitles:QueryList<TabTitle>;

@ContentChildren(TabContent)

tabContents:QueryList<TabContent>;

active:number;

select(index:number){…}

ngAfterViewInit(){…}

}

Inthisimplementation,wehaveadecoratorthatwehaven’tusedyet—[email protected]@ContentChildrenpropertydecoratorfetchesthecontentchildrenofthegivencomponent.ThismeansthatwecangetreferencestoallTabTitleandTabContentinstancesfromwithintheinstanceoftheTabscomponentandgetthemintheorderinwhichtheyaredeclaredinthemarkup.There’sanalternativedecoratorcalled@ViewChildren,whichfetchesalltheviewchildrenofthegivenelement.Let’stakealookatthedifferencebetweenthembeforeweexplaintheimplementationfurther.

Page 218: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ViewChildversusContentChildAlthoughbothconceptssoundsimilar,theyhavequitedifferentsemantics.Inordertounderstandthembetter,let’stakealookatthefollowingexample:

//ch4/ts/view-child-content-child/app.ts

@Component({

selector:'user-badge',

template:'…'

})

classUserBadge{}

@Component({

selector:'user-rating',

template:'…'

})

classUserRating{}

Here,we’vedefinedtwocomponents:UserBadgeandUserRating.Let’sdefineaparentcomponent,whichcomprisesboththecomponents:

@Component({

selector:'user-panel',

template:'<user-badge></user-badge>',

directives:[UserBadge]

})

classUserPanel{…}

NotethatthetemplateoftheviewofUserPanelcontainsonlytheUserBadgecomponent’sselector.Now,let’susetheUserPanelcomponentinourapplication:

@Component({

selector:'app',

template:`<user-panel>

<user-rating></user-rating>

</user-panel>`,

directives:[CORE_DIRECTIVES,UserPanel,UserRating]

})

classApp{

constructor(){}

}

ThetemplateofourmainAppcomponentusestheUserPanelcomponentandneststheUserRatingcomponentinsideit.Now,let’ssupposewewanttogetareferencetotheinstanceoftheUserRatingcomponentthatisusedinsidetheuser-panelelementintheAppcomponentandareferencetotheUserBadgecomponent,whichisusedinsidetheUserPaneltemplate.Inordertodothis,wecanaddtwomorepropertiestotheUserPanelcontrollerandaddthe@ContentChildand@ViewChilddecoratorstothemwiththeappropriatearguments:

classUserPanel{

@ViewChild(UserBadge)

badge:UserBadge;

Page 219: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

@ContentChild(UserRating)

rating:UserRating;

constructor(){

//

}

}

Thesemanticsofthebadgepropertydeclarationisthis:“gettheinstanceofthefirstchildcomponentofthetypeUserBadge,whichisusedinsidetheUserPaneltemplate”.Accordingly,thesemanticsoftheratingproperty’sdeclarationisthis:“gettheinstanceofthefirstchildcomponentofthetypeUserRating,whichisnestedinsidetheUserPanelhostelement”.

Now,ifyourunthiscode,you’llnotethatthevaluesofthebadgeandratingpropertiesarestillequaltotheundefinedvalueinsidethecontroller’sconstructor.Thisisbecausetheyarestillnotinitializedinthisphaseofthecomponent’slifecycle.ThelifecyclehooksthatwecanuseinordertogetareferencetothesechildcomponentsarengAfterViewInitandngAfterContentInit.WecanusethesehookssimplybyaddingdefinitionsofthengAfterViewInitandngAfterContentInitmethodstothecomponent’scontroller.WewillmakeacompleteoverviewofthelifecyclehooksthatAngular2providesshortly.

Torecap,wecansaythatthecontentchildrenofthegivencomponentsarethechildelementsthatarenestedwithinthecomponent’shostelement.Incontrast,theviewchildrendirectivesofthegivencomponentaretheelementsusedwithinitstemplate.

NoteInordertogetplatformindependentreferencetoaDOMelement,again,wecanuse@[email protected],ifwehavethefollowingtemplate:<input#todo>wecangetareferencetotheinputbyusing:@ViewChild('todo').

Sincewearealreadyfamiliarwiththecoredifferencesbetweenviewchildrenandcontentchildrennow,wecancontinuewithourtabsimplementation.

Inthetabscomponent,insteadofusingthe@ContentChilddecorator,weuse@ContentChildren.Wedothisbecausewehavemultiplecontentchildrenandwewanttogetthemall:

@ContentChildren(TabTitle)

tabTitles:QueryList<TabTitle>;

@ContentChildren(TabContent)

tabContents:QueryList<TabContent>;

AnothermaindifferencewecannoticeisthatthetypesofthetabTitlesandtabContentspropertiesareQueryListwiththerespectivetypeparameterandnotthecomponent’stypeitself.WecanthinkoftheQueryListdatastructureasaJavaScriptarray—wecanapplythesamehigh-orderfunctions(map,filter,reduce,andsoon)overitandloopoveritselements;however,QueryListisalsoobservable,thatis,wecanobserveitforchanges.

Page 220: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

AsthefinalstepofourTabsdefinition,let’stakeapeekattheimplementationofthengAfterContentInitandselectmethods:

ngAfterContentInit(){

this.tabTitles

.map(t=>t.tabSelected)

.forEach((t,i)=>{

t.subscribe(_=>{

this.select(i)

});

});

this.active=0;

this.select(0);

}

Inthefirstlineofthemethod’simplementation,weloopalltabTitlesandtaketheobservable’sreferences.Theseobjectshaveamethodcalledsubscribe,whichacceptsacallbackasanargument.Oncethe.emit()methodoftheEventEmitterinstance(thatis,thetabSelectedpropertyofanytab)iscalled,thecallbackpassedtothesubscribemethodwillbeinvoked.

Now,let’stakealookattheselectmethod’simplementation:

select(index:number){

letcontents:TabContent[]=this.tabContents.toArray();

contents[this.active].isActive=false;

this.active=index;

contents[this.active].isActive=true;

this.tabChanged.emit(index);

}

Inthefirstline,wegetanarrayrepresentationoftabContents,whichisofthetypeQueryList<TabContent>.Afterthat,wesettheisActiveflagofthecurrentactivetabtofalseandselectthenextactiveone.Inthelastlineintheselectmethod’simplementation,wetriggertheselectedeventoftheTabscomponentbyinvokingthis.tabChanged.emitwiththeindexofthecurrentlyselectedtab.

Page 221: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 222: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Hookingintothecomponent’slifecycleComponentsinAngular2haveawell-definedlifecycle,whichallowsustohookintodifferentphasesofitandhavefurthercontroloverourapplication.Wecandothisbyimplementingspecificmethodsinthecomponent’scontroller.Inordertobemoreexplicit,thankstotheexpressivenessofTypeScript,wecanimplementdifferentinterfacesassociatedwiththelifecycle’sphases.Eachoftheseinterfaceshasasinglemethod,whichisassociatedwiththephaseitself.

Althoughcodewrittenwithexplicitinterfaceimplementationwillhavebettersemantics,sinceAngular2supportsES5aswellwithinthecomponent,wecansimplydefinemethodswiththesamenamesasthelifecyclehooks(butthistime,prefixedwithng)andtakeadvantageofducktyping.

Thefollowingdiagramshowsallthephaseswecanhookinto:

Let’stakealookatthedifferentlifecyclehooks:

OnChanges:Thishookwillbeinvokedonceachangeintheinputpropertiesofagivencomponenthasbeendetected.Forinstance,let’stakealookatthefollowingcomponent:

@Component({

selector:'panel',

inputs:['title']

})

classPanel{…}

Wecanuseitlikethis:

<panel[title]="expression"></panel>

Oncethevalueoftheexpressionassociatedwiththe[title]attributehasbeenchanged,thengOnChangeshookwillbeinvoked.Wecanimplementitusingthiscodesnippet:

Page 223: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

@Component(…)

classPanel{

ngOnChanges(changes){

Object.keys(changes).forEach(prop=>{

console.log(prop,'changed.Previousvalue',

changes[prop].previousValue);

});

}

}

Theprecedingsnippetwilldisplayallthechangedbindingsandtheiroldvalues.Inordertobemoreexplicitintheimplementationofthehook,wecanuseinterfaces:

import{Component,OnChanges}from'angular2/core';

@Component(…)

classPanelimplementsOnChanges{

ngOnChanges(changes){…}

}

Alltheinterfacesrepresentingtheindividuallifecyclehooksdefineasinglemethodwiththenameoftheinterfaceitselfprefixedwithng.Intheupcominglist,we’llusethetermlifecyclehook,bothforinterfaceand/orthemethod,exceptifwewon’timplyanythingspecificallyforonlyoneofthem.

OnInit:Thishookwillbeinvokedoncethegivencomponenthasbeeninitialized.WecanimplementitusingtheOnInitinterfacewithitsngOnInitmethod.DoCheck:Thiswillbeinvokedwhenthechangedetectorofthegivencomponentisinvoked.Itallowsustoimplementourownchangedetectionalgorithmforthegivencomponent.NotethatDoCheckandOnChangesshouldnotbeimplementedtogetheronthesamedirective.OnDestroy:IfweimplementtheOnDestroyinterfacewithitssinglengOnDestroymethod,wecanhookintothedestroylifecyclephaseofacomponent.Thismethodwillbeinvokedoncethecomponentisdetachedfromthecomponenttree.

Now,let’stakealookatthelifecyclehooksassociatedwiththecomponent’scontentandviewchildren:

AfterContentInit:IfweimplementthengAfterContentInitlifecyclehook,wewillbenotifiedwhenthecomponent’scontenthasbeenfullyinitialized.ThisisthephasewhenthepropertiesdecoratedwithContentChildorContentChildrenwillbeinitialized.AfterContentChecked:Byimplementingthishook,we’llgetnotifiedeachtimethecontentofthegivencomponenthasbeencheckedbythechangedetectionmechanismofAngular2.AfterViewInit:IfweimplementthengAfterViewInitlifecyclehook,wewillbenotifiedwhenthecomponent’sviewhasbeenfullyinitialized.ThisisthephasewhenthepropertiesdecoratedwithViewChildorViewChildrenwillbeinitialized.AfterViewChecked:ThisissimilartoAfterContentChecked.TheAfterViewCheckedhookwillbeinvokedoncetheviewofyourcomponenthasbeenchecked.

Page 224: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 225: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TheorderofexecutionInordertotracetheorderofexecutionofthecallbacksassociatedwitheachhook,let’stakeapeekatthech4/ts/life-cycle/app.tsexample:

@Component({

selector:'panel',

inputs:['title','caption'],

template:'<ng-content></ng-content>'

})

classPanel{

ngOnChanges(changes){…}

ngOnInit(){…}

ngDoCheck(){…}

ngOnDestroy(){…}

ngAfterContentInit(){…}

ngAfterContentChecked(){…}

ngAfterViewInit(){…}

ngAfterViewChecked(){…}

}

ThePanelcomponentimplementsallthehookswithoutexplicitlyimplementingtheinterfacesassociatedwiththem.

Wecanusethecomponentinthefollowingtemplate:

<button(click)="toggle()">Toggle</button>

<div*ngIf="counter%2==0">

<panelcaption="Samplecaption"title="Sample">Helloworld!</panel>

</div>

Intheprecedingexample,wehaveapanelandabutton.Uponeachclickonthebutton,thepanelwillbeeitherremovedorappendedtotheviewbythengIfdirective.

Duringtheapplicationinitialization,iftheresultofthe"counter%2==0"expressionisevaluatedtotrue,thengOnChangesmethodwillbeinvoked.Thishappensbecausethevaluesofthetitleandcaptionpropertiesaregoingtobesetforthefirsttime.

Rightafterthis,thengOnInitmethodwillbecalled,sincethecomponenthasbeeninitialized.Oncethecomponent’sinitializationiscompleted,thechangedetectionwillbetriggered,whichwillleadtotheinvocationofthengDoCheckmethodthatallowsustohookcustomlogicfordetectingchangesinthestate.

NoteNotethatyouarenotsupposedtoimplementbothngDoCheckandngOnChangesmethodsforthesamecomponent,sincetheyaremutuallyexclusive.Theexampleheredoesthisforlearningpurposesonly.

AfterthengDoCheckmethod,thecomponent’scontentwillbefollowedbyperformingacheckonit(ngAfterContentInitandngAfterContentCheckedwillbeinvokedinthisorder).Rightafterthis,thesamewillhappenforthecomponent’sview(ngAfterViewInitfollowedbyngAfterViewChecked).

Page 226: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

OncetheexpressionofthengIfdirectiveisevaluatedtofalse,theentirecomponentwillbedetachedfromtheview,whichwillleadtotheinvocationofthengOnDestroyhook.

Onthenextbuttonclick,ifthevalueoftheexpressionofngIfisequaltotrue,thesamesequenceofcallsofthelifecyclehooksastheoneduringtheinitializationphasewillbeexecuted.

Page 227: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 228: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefininggenericviewswithTemplateRefWearealreadyfamiliarwiththeconceptsofinputs,content,andviewchildren,andwealsoknowwhenwecangetareferencetotheminthecomponent’slifecycle.Now,wewillcombinethemandintroduceanewconcept:TemplateRef.

Let’stakeastepbackandtakealookatthelastto-doapplicationwedevelopedearlierinthischapter.Inthefollowingscreenshot,youcanseewhatitsUIlookslike:

Ifwetakealookatitsimplementationinch4/ts/inputs-outputs/app.ts,we’llseethatthetemplateusedtorendertheindividualto-doitemsisdefinedinsidethetemplateoftheentireto-doapplication.

Whatifwewanttouseadifferentlayouttorendertheto-doitems?WecandothisbycreatinganothercomponentcalledTodo,whichencapsulatestheresponsibilityofrenderingthem.Then,wecandefineseparateTodocomponentsforthedifferentlayoutswewanttosupport.Thisway,weneedtohavendifferentcomponentsforndifferentlayouts,eventhoughweuseonlytheirtemplates.

Angular2comeswithamoreelegantsolution.Earlierinthischapter,wealreadydiscussedthetemplateelement.WesaidthatitallowsustodefineachunkofHTMLthatwillnotbeprocessedbythebrowser.Angular2allowsustoreferencesuchtemplateelementsandusethembypassingthemascontentchildren!

Hereishowwecanpassthecustomlayouttoourrefactoredtodo-appcomponent:

//ch4/ts/template-ref/app.ts

<todo-app>

<templatevar-todo>

<inputtype="checkbox"[checked]="todo.completed"

Page 229: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

(change)="todo.completed=!todo.completed;">

<span[class.completed]="todo.completed">

{{todo.label}}

</span><br>

</template>

</todo-app>

Inthetemplate,wedeclareavariablecalledtodo.Laterinthetemplate,wecanuseittospecifythewayinwhichwewanttovisualizethecontent.

Now,let’sseehowwecangetareferencetothistemplateinthecontrolleroftheTodoAppcomponent:

//ch4/ts/template-ref/app.ts

classTodoApp{

@ContentChild(TemplateRef)

privateitemsTemplate:TemplateRef;

//…

}

AllwedohereisdefineapropertycalleditemsTemplateanddecorateitwiththe@ContentChilddecorator.Duringthecomponent’slifecycle(moreaccurately,inngAfterContentInit),thevalueofitemsTemplatewillbesetasareferenceofthetemplatethatwepassedasthecontentofthetodo-appelement.

Thereisonemoreproblemthough—weneedthetemplateintheTodoListcomponent,sincethat’stheplacewherewerendertheindividualto-doitems.WhatwecandoisdefineanotherinputoftheTodoListcomponentandpassthetemplatedirectlyfromTodoApp:

//ch4/ts/template-ref/app.ts

classTodoList{

@Input()todos:Todo[];

@Input()itemsTemplate:TemplateRef;

@Output()toggle=newEventEmitter<Todo>();

}

WeneedtopassitasaninputfromthetemplateofTodoApp:

...

<todo-list[todos]="todos"

[itemsTemplate]="itemsTemplate">

</todo-list>

TheonlythingleftistousethistemplatereferenceinthetemplateoftheTodoListapplication:

<!--…-->

<template*ngFor="vartodooftodos;template:itemsTemplate"></template>

WeexplainedtheextendedsyntaxofthengForOfdirectiveintheprevioussectionsofthischapter.Thissnippetshowsonemorepropertyofthisdirectivethatwecanset:thengForTemplateproperty.Bydefault,thetemplateofthengForOfdirectiveistheelementitisusedon.ByspecifyingatemplatereferencetothengForTemplateproperty,wecanusethepassedTemplateRefinstead.

Page 230: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 231: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 232: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UnderstandingandenhancingthechangedetectionWealreadybrieflydescribedthechangedetectionmechanismoftheframework.WesaidthatcomparedtoAngularJS1.x,whereitrunsinthecontextofthescope,inAngular2,itrunsinthecontextoftheindividualcomponents.Anotherconceptwementionedisthezones,whichbasicallyinterceptalltheasynchronouscallsthatwecanmakeusingthebrowserAPIsandprovideexecutioncontextforthechangedetectionmechanismoftheframework.ZonesfixtheannoyingproblemwehaveinAngularJS1.x,wherewhenweuseAPIsoutsideofAngular,weneedtoexplicitlyinvokethedigestloop.

InChapters1,GettingStartedwithAngular2andChapter2,TheBuildingBlocksofanAngular2Application,wediscussedthattherearetwomainimplementationsofthechangedetector:DynamicChangeDetectorandJitChangeDetector.ThefirstoneworksgreatforenvironmentswithstrictCSP(Content-Security-Policy)becauseofthedisableddynamicevaluationofJavaScript.Thesecondonetakesgreatbenefitsfromtheinline-cachingmechanismoftheJavaScriptvirtualmachineandthereforebringsgreatperformance!

Inthissection,we’llexploreanotherpropertyofthe@Componentdecorator’sconfigurationobject,whichprovidesusfurthercontroloverthechangedetectionmechanismoftheframeworkbychangingitsstrategy.Byexplicitlysettingthestrategy,weareabletopreventthechangedetectionmechanismfromrunningoveracomponent’ssubtrees,whichinsomecasescanbringgreatperformancebenefits.

Page 233: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TheorderofexecutionofthechangedetectorsNow,let’sbrieflydescribetheorderinwhichthechangedetectorsareinvokedinagivencomponenttree.

Forthispurpose,wewillusethelastimplementationoftheto-doapplicationwehave,butthistime,we’llextractthelogictorendertheindividualto-doitemsintoaseparatecomponentcalledTodoItem.Inthefollowingfigure,wecanseetheapplication’sstructure:

AtthetoplevelistheTodoAppcomponent,whichhastwochildren:InputBoxandTodoList.TheTodoListcomponentrenderstheindividualto-doitemsinTodoItemcomponents.Theimplementationdetailsarenotimportantforourpurpose,sowearegoingtoignorethem.

Now,weneedtorealizethatthereisanimplicitdependencybetweenthestateoftheparentcomponentanditschildren.Forinstance,thestateoftheTodoListcomponentdependscompletelyontheto-doitemsthatarelocatedatitsparent:theTodoAppcomponent.There’sasimilardependencybetweenTodoItemandTodoList,sincetheTodoListcomponentpassestheindividualto-doitemstoaseparateinstanceoftheTodoItemcomponent.

Page 234: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Becauseofourlastobservation,theorderofexecutionofthechangedetectorsattachedtotheindividualcomponentsisliketheoneshownontheprecedingfigure.Oncethechangedetectionmechanismrun,initiallyitwillperformacheckovertheTodoAppcomponent.Rightafterthis,theInputBoxcomponentwillbecheckedforchanges,followedbytheTodoListcomponent.Intheend,AngularwillinvokethechangedetectoroftheTodoItemcomponent.

Youcantracetheorderofexecutioninthech4/ts/change_detection_strategy_order/app.tsexample,whereeachindividualcomponentlogsamessageonceitsngDoCheckmethodisinvoked.

NoteNotethatonlythecomponentshaveaninstanceofachangedetectorattachedtothem;directivesusethechangedetectoroftheirparentcomponent.

Page 235: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ChangedetectionstrategiesThechangedetectionstrategiesthatAngular2providesare:CheckOnce,Checked,CheckAlways,Detached,Default,andOnPush.WewilldescribehowwecantakeadvantageofOnPushindetail,sinceitisverypowerfulwhenworkingwithimmutabledata.BeforetakingadeepdiveintoOnPush,let’sbrieflydescribetheotherstrategies.

Now,let’simporttheTypeScriptenum,whichcanbeusedtoconfigurethestrategyusedfortheindividualcomponents:

//ch4/ts/change_detection_strategy_broken/app.ts

import{ChangeDetectionStrategy}from'angular2/core';

Now,wecanconfiguretheTodoListcomponenttousetheCheckedstrategy:

@Component({

selector:'todo-list',

changeDetection:ChangeDetectionStrategy.Checked,

template:`...`,

styles:[…]

})

classTodoList{…}

Thisway,thechangedetectionwillbeskippeduntilitsmode(strategy)changestoCheckOnce.Butwhatdoesitmeantopreventthechangedetectionfromrunning?Youcangotohttp://localhost:5555/dist/dev/ch4/ts/change_detection_strategy_broken/andseetheinconsistentbehavioroftheTodoListcomponent.Whenyouaddanewto-doitemintheinputandyouclickonthebutton,itwon’timmediatelyappearinthelist.

Now,let’stryCheckOnce!Insidech4/ts/change_detection_strategy_broken/app.ts,changethechangedetectionstrategyoftheTodoListcomponenttoChangeDetectionStrategy.CheckOnce.Afterrefreshingthebrowser,trytoaddanewto-doitem.ThechangeshouldnotbeimmediatelyreflectedbecauseCheckOncewillinstructthechangedetectortoperformthecheckonlyonce(inthiscase,duringinitialization),andafterthat,nothingwillhappen.

Bydefault,itisusedintheCheckAlwaysmode,whichasitsnamestates,doesn’tpreventthechangedetectorfromrunning.

IfwedeclarethestrategyofagivencomponenttoDetached,thechangedetectorsubtreewillnotbeconsideredasapartofthemaintreeandwillbeskipped.

Page 236: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

PerformanceboostingwithimmutabledataandOnPushThelastchangedetectionstrategythatwearegoingtodescribeisOnPush.Itisextremelyusefulwhentheresultthatthegivencomponentproducesdependsonlyonitsinputs.Insuchcases,wecanpassimmutabledatatotheinputsinordertomakesurethatitwillnotbemutatedbyanyothercomponent.Thisway,byhavingacomponentthatdependsonlyonitsimmutableinputs,wecanmakesurethatitproducesdifferentuserinterfacesonlyonceitreceivesdifferentinputs(thatis,differentreference).

Inthissection,wearegoingtoapplytheOnPushstrategyontheTodoListcomponent.Sinceitdependsonlyonitsinputs(thetodosinput),wewanttomakesurethatitschangedetectionwillbeperformedonlyonceitreceivesanewreferenceofthetodoscollection.

Theessenceofimmutabledataisthatitcannotchange.Thismeansthatonceweaddanewto-doitemtothetodoscollection,wecannotchangeit;instead,theadd(orinourcase,push)methodwillreturnanewcollection—acopyoftheinitialcollectionwiththenewitemincluded.

Thismayseemlikeahugeoverhead—tocopytheentirecollectiononeachchange.Inbigapplications,thismayhaveabigperformanceimpact.However,wedon’tneedtocopytheentirecollection.Therearelibrariesthatimplementimmutabledatastructureusingsmarteralgorithms:persistentdatastructures.Persistentdatastructuresareoutofthescopeofthecurrentcontent.Furtherinformationaboutthemcanbefoundinmostcomputersciencetextbooksforadvanceddatastructures.Thegoodthingisthatwedon’thavetounderstandtheirimplementationindepthinordertousethem!ThereisalibrarycalledImmutable.jsthatimplementsafewcommonlyusedimmutabledatastructures.Inourcase,wearegoingtousetheimmutablelist.Generally,theimmutablelistbehavesjustlikeanormallist,butoneachoperationthatissupposedtomutateit,itreturnsanewlist.

Thismeansthatifwehavealistcalledfoo,whichisimmutable,andweappendanewitemtothelist,wearegoingtogetanewreference:

letfoo=List.of(1,2,3);

letchanged=foo.push(4);

foo===changed//false

console.log(foo.toJS());//[1,2,3]

console.log(changed.toJS());//[1,2,3,4]

Inordertotakeadvantageofimmutability,weneedtoinstallImmutable.jsusingnpm.

We’vealreadydonethisinch4/ts/change_detection_strategy/app.ts.Immutable.jsisalreadypartofpackage.json,whichislocatedattherootdirectoryoftheproject.

Now,it’stimetorefactorourto-doapplicationandmakeituseimmutabledata!

Page 237: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingimmutabledatastructuresinAngularLet’stakealookathowwecurrentlykeeptheto-doitemsintheTodoAppcomponent:

classTodoApp{

todos:Todo[]=[...];

...

}

WeuseanarrayofTodoitems.TheJavaScriptarrayismutable,whichmeansthatifwepassittoacomponentthatusestheOnPushstrategy,itisnotsafetoskipthechangedetectionincasewegetthesameinputreference.Forinstance,wemayhavetwocomponentsthatusethesamelistofto-doitems.Bothcomponentscanmodifythelistsinceitismutable.Thiswillleadtoaninconsistentstatetoanyofthecomponentsincasetheirchangedetectionisnotperformed.That’swhyweneedtomakesurethatthelistthatholdstheitemsisimmutable.AllweneedtodointheTodoAppcomponentinordertomakesurethatitholdsitsdatainanimmutabledatastructureisthis:

//ch4/ts/change_detection_strategy/app.ts

classTodoApp{

todos:ImmutableList<Todo>=ImmutableList.of({

label:'Buymilk',

completed:false

},{

label:'Savetheworld',

completed:false

});

...

}

Inthisway,weconstructthetodospropertyasanimmutablelist.Sincethemutationoperationsoftheimmutablelistreturnanewlist,weneedtomakeaslightmodificationinaddTodoandtoggleTodoCompletion:

...

addTodo(label:string){

this.todos=this.todos.push({

label,

completed:false

});

}

toggleCompletion(index:number){

this.todos=this.todos.update(index,todo=>{

letnewTodo={

label:todo.label,

completed:!todo.completed

};

returnnewTodo;

});

}

TheaddTodofunctionlooksexactlythesameasbeforeexceptthatwesettheresultofthepushmethodasavaluetothetodosproperty.

Page 238: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

IntoggleTodoCompletion,weusetheupdatemethodoftheimmutablelist.Asthefirstargument,wepasstheindexoftheto-doitemwewanttomodify,andthesecondargumentisacallbackthatdoestheactualmodification.Notethatsinceweareusingimmutabledatainthiscase,wecopythemodifiedto-doitem.Thisisrequiredbecauseittellstheupdatemethodthattheitemwiththegivenindexhasbeenchanged(sinceitisimmutable,itisconsideredaschangedonlywhenithasanewreference),whichmeansthattheentirelisthasbeenchanged.

Thatwasthecomplexpart!Nowlet’stakealookattheTodoListcomponent’sdefinition:

@Component({

selector:'todo-list',

changeDetection:ChangeDetectionStrategy.OnPush,

template:`...`,

styles:[...]

})

classTodoList{

@Input()todos:ImmutableList<Todo>;

@Output()toggle=newEventEmitter<number>();

toggleCompletion(index:number){

this.toggle.emit(index);

}

}

Insidethe@Componentdecorator,wesetthechangeDetectionpropertytothevalueoftheOnPushstrategy.Thismeansthatthecomponentwillrunitschangedetectoronlywhenanyofitsinputsgetsanewreference.ThetemplateofthecomponentstaysexactlythesamesincengForOfinternallyusesES2015iteratorstolooptheitemsintheprovidedcollection.TheyaresupportedbyImmutable.js,sothechangesinthetemplatearenotrequired.

Sinceweneedtheindexofthechangeditem(theoneweuseintheupdatemethodofthetodoscollectioninTodoApp),wechangethetypeoftheoutputofthecomponenttoEventEmitter<number>.IntoggleCompletion,weemittheindexofthechangedto-doitem.

Thisishowweoptimizedoursimpleto-doapplicationbypreventingthechangedetectionmechanismfromrunningintheentirerightsubtreeincasetheparentcomponenthasn’tpushedaninputwithanewreference.

Page 239: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 240: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SummaryInthischapter,wewentthroughthecorebuildingblocksofanAngular2application:directivesandcomponents.Webuiltacoupleofsamplecomponents,whichshowusthesyntaxtobeusedforthedefinitionofthesefundamentalconcepts.Wealsodescribedthelifecycleofeachdirectiveandthecoresetoffeaturesthegivendirectiveandcomponenthave.Asthenextstep,wesawhowwecanenhancetheperformanceofourapplicationbyusingtheOnPushchangedetectionstrategywithimmutabledata.

ThenextchapteriscompletelydedicatedtotheAngular2servicesandthedependencyinjectionmechanismoftheframework.Wearegoingtolookathowwecandefineandinstantiatecustominjectorsandhowwecantakeadvantageofthedependencyinjectionmechanisminourdirectivesandcomponents.

Page 241: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 242: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Chapter5.DependencyInjectioninAngular2Inthischapter,we’llexplainhowtotakeadvantageofthedependencyinjection(DI)mechanismoftheframeworkwithallitsvariousfeatures.

Wewillexplorethefollowingtopics:

Configuringandcreatinginjectors.Instantiatingobjectsusinginjectors.Injectingdependenciesintoourdirectivesandcomponents.Thisway,wewillbeabletoreusethebusinesslogicdefinedwithintheservicesandwireitupwiththeUIlogic.AnnotatingtheES5codewewillwriteinordertogettheexactsameresultwegetwhenweareusingtheTypeScriptsyntax.

Page 243: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WhydoIneedDependencyInjection?Let’ssupposethatwehaveaCarclassthatdependsontheEngineandTransmissionclasses.Howcanweimplementthissystem?Let’stakealook:

classEngine{…}

classTransmission{…}

classCar{

engine;

transmission;

constructor(){

this.engine=newEngine();

this.transmission=newTransmission();

}

}

Inthisexample,wecreatedthedependenciesoftheCarclassinsideofitsconstructor.Althoughitlookssimple,itisfarfrombeingflexible.EachtimewecreateaninstanceoftheCarclass,instancesofthesameEngineandTransmissionclasseswillbecreated.Thismaybeproblematicbecauseofthefollowingreasons:

TheCarclassgetslesstestablebecausewecan’ttestitindependentlyfromitsengineandtransmissiondependencies.WecoupletheCarclasswiththelogicusedfortheinstantiationofitsdependencies.

Page 244: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 245: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DependencyInjectioninAngular2AnotherwaywecanapproachthisisbytakingadvantageoftheDIpattern.We’realreadyfamiliarwithitfromAngularJS1.x.Let’sdemonstratehowwecanrefactortheprecedingcodeusingDIinthecontextofAngular2:

classEngine{…}

classTransmission{…}

@Injectable()

classCar{

engine;

transmission;

constructor(engine:Engine,transmission:Transmission){

this.engine=engine;

this.transmission=transmission;

}

}

Allwedidintheprecedingsnippetwasaddthe@InjectableclassdecoratorontopofthedefinitionoftheCarclassandprovidetypeannotationsfortheparametersofitsconstructor.

Page 246: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

BenefitsofDIinAngular2Thereisonemorestepleft,whichwe’lltakealookatinthenextsection.Butlet’sseewhatthebenefitsofthementionedapproachare:

WecaneasilypassdifferentversionsofthedependenciesoftheCarclassforatestingenvironment.We’renotcoupledwiththelogicaroundthedependencies’instantiation.

TheCarclassisonlyresponsibleforimplementingitsowndomain-specificlogicinsteadofbeingcoupledwithadditionalfunctionalities,suchasthemanagementofitsdependencies.Ourcodealsogotmoredeclarativeandeasiertoread.

Now,afterwe’verealizedsomeofthebenefitsoftheDI,let’stakealookatthemissingpiecesinordertomakethiscodework!

Page 247: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 248: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ConfiguringaninjectorTheprimitiveusedfortheinstantiationoftheindividualdependenciesinourAngular2applicationsviatheDImechanismoftheframeworkiscalledtheinjector.Theinjectorcontainsasetofprovidersthatencapsulatethelogicfortheinstantiationofregistereddependenciesassociatedwithtokens.Wecanthinkoftokensasidentifiersofthedifferentprovidersregisteredwithintheinjector.

Let’stakealookatthefollowingsnippet,whichislocatedatch5/ts/injector-basics/injector.ts:

import'reflect-metadata';

import{

Injector,Inject,Injectable,

OpaqueToken,provide

}from'angular2/core';

constBUFFER_SIZE=newOpaqueToken('buffer-size');

classBuffer{

constructor(@Inject(BUFFER_SIZE)privatesize:Number){

console.log(this.size);

}

}

@Injectable()

classSocket{

constructor(privatebuffer:Buffer){}

}

letinjector=Injector.resolveAndCreate([

provide(BUFFER_SIZE,{useValue:42}),

Buffer,

Socket

]);

injector.get(Socket);

Youcanrunthefileusingthefollowingcommand:

cdapp

ts-nodech5/ts/injector-basics/injector.ts

Ifyouhaven’tinstalledts-nodeyet,takealookatChapter3,TypeScriptCrashCourse,whichexplainshowyoucanproceedinordertohaveitupandrunningonyourcomputer.

WeimportInjector,Injectable,Inject,OpaqueToken,andprovide.

Injectorrepresentsthecontainerusedfortheinstantiationofthedifferentdependencies.UsingtherulesdeclaredwiththeprovidefunctionandthemetadatageneratedbytheTypeScriptcompiler,itknowshowtocreatethem.

Intheprecedingsnippet,weinitiallydefinedtheBUFFER_SIZEconstantandsetittothenewOpaqueToken('buffer-size')value.WecanthinkofthevalueofBUFFER_SIZEasa

Page 249: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

uniquevaluethatcannotbeduplicatedintheapplication(OpaqueTokenisanalternativeoftheSymbolclassfromES2015,sinceatthetimeofwritingthis,itisnotsupportedbyTypeScript).

Wedefinedtwoclasses:BufferandSocket.TheBufferclasshasaconstructorthatacceptsonlyasingledependencycalledsize,whichisofthetypeNumber.Inordertoaddadditionalmetadatafortheprocessofdependencyresolution,weusethe@Injectparameterdecorator.Thisdecoratoracceptsanidentifier(alsoknownastoken)ofthedependencywewanttoinject.Usually,itisthetypeofthedependency(thatis,areferenceofaclass),butinsomecases,itcanbeadifferenttypeofavalue.Forexample,inourcase,weusedtheinstanceoftheOpaqueTokenclass.

Page 250: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DependencyresolutionwithgeneratedmetadataNowlet’stakealookattheSocketclass.Wedecorateitwiththe@Injectabledecorator.ThisdecoratorissupposedtobeusedbyanyclassthatacceptsdependenciesthatshouldbeinjectedviathedependencyinjectionmechanismofAngular2.

The@InjectabledecoratorforcestheTypeScriptcompilertogenerateadditionalmetadataforthetypesofdependenciesthatagivenclassaccepts.Thismeansthatifweomitthe@Injectabledecorator,Angular’sDImechanismwillnotbeawareofthetokensassociatedwiththedependenciesitneedstoresolve.

TypeScriptdoesn’tgenerateanymetadataifnodecoratorisusedontopofaclassmostlyforperformanceconcerns.Imagineifsuchmetadatawasgeneratedforeachindividualclassthatacceptsdependencies—inthiscase,theoutputwouldbebloatedwithadditionaltypemetadatathatwouldbeunused.

Analternativetousing@Injectableistoexplicitlydeclarethetypesofdependenciesusingthe@Injectdecorator.Takealookatthefollowing:

classSocket{

constructor(@Inject(Buffer)privatebuffer:Buffer){}

}

Thismeansthattheprecedingcodehasequivalentsemanticstothecodethatuses@Injectable,asmentionedearlier.TheonlydifferenceisthatAngular2willgetthetypeofdependency(thatis,thetokenassociatedwithit)explicitly(directlyfromthemetadataaddedbythe@Injectordecorator)comparedtothecasewhere@Injectableisused,whenitwilllookatthemetadatageneratedbythecompiler.

Page 251: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

InstantiatinganinjectorNow,let’screateaninstanceofaninjectorinordertouseitfortheinstantiationofregisteredtokens:

letinjector=Injector.resolveAndCreate([

provide(BUFFER_SIZE,{useValue:42}),

Buffer,

Socket

]);

WecreateaninstanceoftheInjectorusingitsstaticmethodcalledresolveAndCreate.ThisisafactorymethodthatacceptsanarrayofprovidersasargumentandreturnsanewInjector.

resolvemeansthattheproviderswillgothrougharesolutionprocess,whichincludessomeinternalprocessing(flatteningmultiplenestedarraysandconvertingindividualprovidersintoanarray).Later,theinjectorcaninstantiateanyofthedependenciesforwhichwehaveregisteredprovidersbasedontherulestheprovidersencapsulate.

Inourcase,weusedtheprovidemethodinordertoexplicitlytelltheAngular2DImechanismtousethevalue42whentheBUFFER_SIZEtokenisrequired.Theothertwoprovidersareimplicit.Angular2willinstantiatethembyinvokingtheprovidedclasswiththenewoperatoroncealloftheirdependenciesareresolved.

WerequesttheBUFFER_SIZEvalueintheconstructoroftheBufferclass:

classBuffer{

constructor(@Inject(BUFFER_SIZE)privatesize:Number){

console.log(this.size);

}

}

Intheprecedingexample,weusedthe@Injectparameterdecorator.IthintstheDImechanismthatthefirstargumentoftheconstructoroftheBufferclassshouldbeinstantiatedwiththeproviderassociatedwiththeBUFFER_SIZEtokenpassedtotheinjector.

Page 252: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

IntroducingforwardreferencesAngular2introducedtheconceptofforwardreferences.Itisrequiredduetothefollowingreasons:

ES2015classesarenothoisted.Allowresolutionofthedependenciesthataredeclaredafterthedeclarationofthedependentproviders.

Inthissection,we’regoingtoexplaintheproblemthatforwardreferencessolveandthewaywecantakeadvantageofthem.

Now,let’ssupposethatwehavedefinedtheBufferandSocketclassesintheoppositeorder:

//ch5/ts/injector-basics/forward-ref.ts

@Injectable()

classSocket{

constructor(privatebuffer:Buffer){…}

}

//undefined

console.log(Buffer);

classBuffer{

constructor(@Inject(BUFFER_SIZE)privatesize:Number){…}

}

//[Function:Buffer]

console.log(Buffer);

Here,wehavetheexactsamedependenciesasintheonesinthepreviousexample,butinthiscase,theSocketclassdefinitionprecedesthedefinitionoftheBufferclass.NotethatthevalueoftheBufferidentifierwillequalundefineduntiltheJavaScriptvirtualmachineevaluatesthedeclarationoftheBufferclass.However,themetadataforthetypesofdependenciesthatSocketacceptswillbegeneratedandplacedrightaftertheSocketclassdefinition.ThismeansthatalongwiththeinterpretationofthegeneratedJavaScript,thevalueoftheBuffertokenwillequalundefined—thatis,asatypeofdependency(orinthecontextoftheDImechanismofAngular2,itstoken),theframeworkwillgetaninvalidvalue.

Runningtheprecedingsnippetwillresultinaruntimeerrorofthefollowingform:

Error:CannotresolveallparametersforSocket(undefined).Makesurethey

allhavevalidtypeorannotations.

Thebestwaytoresolvethisissueisbyswappingthedefinitionswiththeirproperorder.AnotherwaywecanproceedistotakeadvantageofasolutionthatAngular2provides:aforwardreference:

import{forwardRef}from'angular2/core';

Page 253: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

@Injectable()

classSocket{

constructor(@Inject(forwardRef(()=>Buffer))

privatebuffer:Buffer){}

}

classBuffer{…}

Theprecedingsnippetdemonstrateshowwecantakeadvantageofforwardreferences.Allweneedtodoisusethe@InjectparameterdecoratorandpasstheresultoftheinvocationoftheforwardReffunctiontoit.TheforwardReffunctionisahigher-orderfunctionthatacceptsasingleargument—anotherfunctionthatisresponsibleforreturningthetokenassociatedwiththedependency(ormorepreciselyassociatedwithitsprovider)thatneedstobeinjected.Thisway,theframeworkprovidesawaytodefertheprocessofresolvingthetypes(tokens)ofdependencies.

ThetokenofthedependencywillberesolvedthefirsttimeSocketneedstobeinstantiated,unlikethedefaultbehaviorinwhichthetokenisrequiredatthetimeofthedeclarationofthegivenclass.

Page 254: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ConfiguringprovidersNow,let’stakealookatanexamplesimilartotheoneusedearlierbutwithadifferentconfigurationoftheinjector:

letinjector=Injector.resolveAndCreate([

provide(BUFFER_SIZE,{useValue:42}),

provide(Buffer,{useClass:Buffer}),

provide(Socket,{useClass:Socket})

]);

Inthiscase,insideoftheprovider,weexplicitlydeclaredthatwewanttheBufferclasstobeusedfortheconstructionofthedependencywithatokenequaltothereferenceoftheBufferclass.WedotheexactsamethingforthedependencyassociatedwiththeSockettoken;butthistime,weprovidetheSocketclassinstead.ThisishowAngular2willproceedwhenweomitthecalloftheprovidefunctionandpassonlyareferencetoaclassinstead.

Explicitlydeclaringtheclassusedfortheinstantiationofthesameclassmayseemquiteworthless,andgiventheexampleswelookedatsofar,this’llbecompletelycorrect.Insomecases,however,wemightwanttoprovideadifferentclassfortheinstantiationofadependencyassociatedwithgivenclasstoken.

Forinstance,let’ssupposewehavetheHttpservicethatisusedinaservicecalledUserService:

classHttp{…}

@Injectable()

classUserService{

constructor(privatehttp:Http){}

}

letinjector=Injector.resolveAndCreate([

UserService,

Http

]);

TheUserServiceserviceusesHttpforcommunicationwithaRESTfulservice.WecaninstantiateUserServiceusinginjector.get(UserService).Thisway,theconstructorofUserServiceinvokedbytheinjector’sgetmethodwillacceptaninstanceoftheHttpserviceasanargument.However,ifwewanttotestUserService,wedon’treallyneedtomakeHTTPcallstotheRESTfulservice.Incaseofunittesting,wecanprovideadummyimplementationthatwillonlyfaketheseHTTPcalls.InordertoinjectaninstanceofadifferentclasstotheUserServiceservice,wecanchangetheconfigurationoftheinjectortothefollowing:

classDummyHttp{…}

//...

letinjector=Injector.resolveAndCreate([

Page 255: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UserService,

provide(Http,{useClass:DummyHttp})

]);

Now,whenweinstantiateUserService,it’sconstructorwillreceiveareferencetoaninstanceoftheDummyHttpservice.Thiscodeisavailableatch5/ts/configuring-providers/dummy-http.ts.

UsingexistingprovidersAnotherwaytoproceedisusingtheuseExistingpropertyoftheprovider’sconfigurationobject:

//ch5/ts/configuring-providers/existing.ts

letinjector=Injector.resolveAndCreate([

DummyService,

provide(Http,{useExisting:DummyService}),

UserService

]);

Intheprecedingsnippet,weregisteredthreetokens:DummyService,UserService,andHttp.WedeclaredthatwewanttobindtheHttptokentotheexistingtoken,DummyService.ThismeansthatwhentheHttpserviceisrequested,theinjectorwillfindtheproviderforthetokenusedasthevalueoftheuseExistingpropertyandinstantiateitorgetthevalueassociatedwithit.WecanthinkofuseExistingascreatinganaliasofthegiventoken:

letdummyHttp={

get(){},

post(){}

};

letinjector=Injector.resolveAndCreate([

provide(DummyService,{useValue:dummyHttp}),

provide(Http,{useExisting:DummyService}),

UserService

]);

console.assert(injector.get(UserService).http===dummyHttp);

TheprecedingsnippetwillcreateanaliasoftheHttptokentotheDummyHttptoken.ThismeansthatoncetheHttptokenisrequested,thecallwillbeforwardedtotheproviderassociatedwiththeDummyHttptoken,whichwillberesolvedtothevaluedummyHttp.

Page 256: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 257: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningfactoriesforinstantiatingservicesNow,let’ssupposewewanttocreateacomplexobject,forexample,onethatrepresentsaTransportLayerSecurity(TLS)connection.Afewofthepropertiesofsuchanobjectareasocket,asetofcryptoprotocols,andacertificate.Inthecontextofthisproblem,thefeaturesoftheDImechanismofAngular2wehavesofarlookedatmightseemabitlimited.

Forexample,wemightneedtoconfiguresomeofthepropertiesoftheTLSConnectionclasswithoutcouplingtheprocessofitsinstantiationwithalltheconfigurationdetails(chooseappropriatecryptoalgorithms,opentheTCPsocketoverwhichwewillestablishthesecureconnection,andsoon).

Inthiscase,wecantakeadvantageoftheuseFactorypropertyoftheprovider’sconfigurationobject:

letinjector=Injector.resolveAndCreate([

provide(TLSConnection,{

useFactory:(socket:Socket,certificate:Certificate,crypto:Crypto)

=>{

letconnection=newTLSConnection();

connection.certificate=certificate;

connection.socket=socket;

connection.crypto=crypto;

socket.open();

returnconnection;

},

deps:[Socket,Certificate,Crypto]

}),

provide(BUFFER_SIZE,{useValue:42}),

Buffer,

Socket,

Certificate,

Crypto

]);

Theprecedingcodeseemsabitcomplexatfirst,butlet’stakealookatitstepbystep.Wecanstartwiththepartswe’realreadyfamiliarwith:

letinjector=Injector.resolveAndCreate([

...

provide(BUFFER_SIZE,{useValue:42}),

Buffer,

Socket,

Certificate,

Crypto

]);

Initially,weregisteredanumberofproviders:Buffer,Socket,Certificate,andCrypto.Justlikeintheprecedingexample,wealsoregisteredtheBUFFER_SIZEtokenand

Page 258: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

associateditwiththevalue42.ThismeansthatwecanalreadycreateobjectsoftheBuffer,Socket,Certificate,andCryptotypes:

//bufferwithsize42

console.log(injector.get(Buffer));

//socketwithbufferwithsize42

console.log(injector.get(Socket));

WecancreateandconfigureaninstanceoftheTLSConnectionobjectinthefollowingway:

letconnection=newTLSConnection();

connection.certificate=certificate;

connection.socket=socket;

connection.crypto=crypto;

socket.open();

returnconnection;

Now,ifweregisteraproviderthathastheTLSConnectiontokenasadependency,wewillpreventthedependencyinjectionmechanismofAngularfromtakingcareofthedependencyresolutionprocess.Inordertohandlethisproblem,wecanusetheuseFactorypropertyoftheprovider’sconfigurationobject.Thisway,wecanspecifyafunctioninwhichwecanmanuallycreatetheinstanceoftheobjectassociatedwiththeprovider’stoken.WecanusetheuseFactorypropertytogetherwiththedepspropertyinordertospecifythedependenciestobepassedtothefactory:

provide(TLSConnection,{

useFactory:(socket:Socket,certificate:Certificate,crypto:Crypto)=>

{

//...

},

deps:[Socket,Certificate,Crypto]

})

Intheprecedingsnippet,wedefinedthefactoryfunctionusedfortheinstantiationofTLSConnection.Asdependencies,wedeclaredSocket,Certificate,andCrypto.ThesedependenciesareresolvedbytheDImechanismofAngular2andinjectedtothefactoryfunction.Youcantakealookattheentireimplementationandplaywithitatch5/ts/configuring-providers/factory.ts.

Page 259: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 260: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ChildinjectorsandvisibilityInthissection,we’regoingtotakealookathowwecanbuildahierarchyofinjectors.ThisisacompletelynewconceptintroducedbyAngular2.Eachinjectorcanhavezerooroneparentinjectorsandeachparentinjectorcanhavezeroormorechildren,respectively.IncontrasttoAngularJS1.x,wherealltheregisteredprovidersarestoredinaflatstructureinAngular2,theyarestoredinatree.Theflatstructureismorelimited;forinstance,itdoesn’tsupportthenamespacingoftokens;thatis,wecannotdeclaredifferentprovidersforthesametoken,whichmightberequiredinsomecases.Sofar,welookedatanexampleofinjectorthatdoesn’thaveanychildrenoraparent.Nowlet’sbuildahierarchyofinjectors!

Inordertogainabetterunderstandingofthishierarchicalstructureofinjectors,let’stakealookatthefollowingfigure:

Here,weseeatreewhereeachnodeisaninjectorandeachoftheseinjectorskeepsareferencetoitsparent.InjectorHousehasthreechildinjectors:Bathroom,Kitchen,andGarage.

Garagehastwochildren:CarandStorage.Wecanthinkoftheseinjectorsascontainerswithregisteredprovidersinsideofthem.

Let’ssupposewewanttogetthevalueoftheproviderassociatedwiththetokenTire.IfweusetheinjectorCar,thismeansthatAngular2’sDImechanismwilltrytofindtheproviderassociatedwiththistokeninCarandallofitsparents,GarageandHouse,untilitfindsit.

Page 261: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

BuildingahierarchyofinjectorsInordertogainabetterunderstandingofthepreviousparagraph,let’stakealookatthissimpleexample:

//ch5/ts/parent-child/simple-example.ts

classHttp{}

@Injectable()

classUserService{

constructor(publichttp:Http){}

}

letparentInjector=Injector.resolveAndCreate([

Http

]);

letchildInjector=parentInjector.resolveAndCreateChild([

UserService

]);

//UserService{http:Http{}}

console.log(childInjector.get(UserService));

//true

console.log(childInjector.get(Http)===parentInjector.get(Http));

Theimportsareomitted,sincetheyarenotessentialtoexplaintheprecedingsnippet.Wehavetwoservices,HttpandUserService,whereUserServicedependsontheHttpservice.

Initially,wecreatedaninjectorusingtheresolveAndCreatestaticmethodoftheInjectorclass.Wepassedanimplicitprovidertothisinjector,whichwilllaterberesolvedtoaproviderwithanHttptoken.UsingresolveAndCreateChild,weresolvedthepassedprovidersandinstantiatedaninjector,whichpointstoparentInjector(sowegetthesamerelationastheonebetweenGarageandHouseonthediagramabove).

Now,usingchildInjector.get(UserService),weareabletogetthevalueassociatedwiththeUserServicetoken.Similarly,usingchildInjector.get(Http)andparentInjector.get(Http),wegetthesamevalueassociatedwiththeHttptoken.ThismeansthatchildInjectorasksitsparentforthevalueassociatedwiththerequestedtoken.

However,ifwetrytouseparentInjector.get(UserService),wewon’tbeabletogetthevalueassociatedwiththetoken,sinceinthisinjector,wedon’thavearegisteredproviderwiththistoken.

Page 262: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ConfiguringdependenciesNowthatwe’refamiliarwiththeinjectors’hierarchy,let’sseehowwecangetthedependenciesfromtheappropriateinjectorsinit.

Usingthe@SelfdecoratorNowlet’ssupposewehavethefollowingconfiguration:

abstractclassChannel{}

classHttpextendsChannel{}

classWebSocketextendsChannel{}

@Injectable()

classUserService{

constructor(publicchannel:Channel){}

}

letparentInjector=Injector.resolveAndCreate([

provide(Channel,{useClass:Http})

]);

letchildInjector=parentInjector.resolveAndCreateChild([

provide(Channel,{useClass:WebSocket}),

UserService

]);

WecaninstantiatetheUserServicetokenusing:

childInjector.get(UserService);

InUserService,wecandeclarethatwewanttogettheChanneldependencyfromthecurrentinjector(thatis,childInjector)usingthe@Selfdecorator:

@Injectable()

classUserService{

constructor(@Self()publicchannel:Channel){}

}

AlthoughthisisgoingtobethedefaultbehaviorduringtheinstantiationoftheUserService,using@Self,wecanbemoreexplicit.Let’ssupposewechangetheconfigurationofchildInjectortothefollowing:

letparentInjector=Injector.resolveAndCreate([

provide(Channel,{useClass:Http})

]);

letchildInjector=parentInjector.resolveAndCreateChild([

UserService

]);

Ifwekeepthe@SelfdecoratorintheUserServiceconstructorandtrytoinstantiateUserServiceusingchildInjector,wewillgetaruntimeerrorbecauseofthemissingproviderforChannel.

Skippingtheselfinjector

Page 263: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Insomecases,especiallywhileinjectingthedependenciesofUIcomponents,wemaywanttousetheproviderregisteredintheparentinjectorinsteadoftheoneregisteredinthecurrentinjector.Wecanachievethisbehaviorbytakingadvantageofthe@SkipSelfdecorator.Forinstance,let’ssupposewehavethefollowingdefinitionoftheclassContext:

classContext{

constructor(publicparentContext:Context){}

}

EachinstanceoftheContextclasshasaparent.Nowlet’sbuildahierarchyoftwoinjectors,whichwillallowustocreateacontextwithaparentcontext:

letparentInjector=Injector.resolveAndCreate([

provide(Context,{useValue:newContext(null)})

]);

letchildInjector=parentInjector.resolveAndCreateChild([

Context

]);

Sincetherootcontextdoesn’thaveaparent,wewillsetthevalueofitsprovidertobenewContext(null).

Ifwewanttoinstantiatethechildcontext,wecanuse:

childInjector.get(Context);

Fortheinstantiationofthechild,ContextwillbeusedbytheproviderregisteredwithinthechildInjector.However,asadependencyitacceptsanobjectwhichisaninstanceoftheContextclass.Suchclassesexistinthesameinjector,whichmeansthatAngularwilltrytoinstantiateit,butithasadependencyoftheContexttype.Thisprocesswillleadtoaninfiniteloopthatwillcausearuntimeerror.

Inordertopreventitfromhappening,wecanchangethedefinitionofContextinthefollowingway:

classContext{

constructor(@SkipSelf()publicparentContext:Context){}

}

Theonlychangethatweintroducedistheadditionoftheparameterdecorator@SkipSelf.

HavingoptionaldependenciesAngular2introducesthe@Optionaldecorator,whichallowsustodealwithdependenciesthatdon’thavearegisteredproviderassociatedwiththem.Supposeadependencyofaproviderisnotavailableinanyofthetargetinjectorsresponsibleforitsinstantiation.Ifweusethe@Optionaldecorator,duringtheinstantiationofthedependentproviderforvalueofthemissingdependencywillbepassednull.

Nowlet’stakealookatthefollowingexample:

abstractclassSortingAlgorithm{

abstractsort(collection:BaseCollection):BaseCollection;

Page 264: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

}

@Injectable()

classCollectionextendsBaseCollection{

privatesort:SortingAlgorithm;

constructor(sort:SortingAlgorithm){

super();

this.sort=sort||this.getDefaultSort();

}

}

letinjector=Injector.resolveAndCreate([

Collection

]);

Inthiscase,wedefinedanabstractclasscalledSortingAlgorithmandaclasscalledCollection,whichacceptsaninstanceofaconcreteclassasadependencythatextendsSortingAlgorithm.InsideoftheCollectionconstructor,wesetthesortinstancepropertytothepasseddependencyoftheSortingAlgorithmtypeoradefaultsortingalgorithmimplementation.

Wedidn’tdefineanyprovidersfortheSortingAlgorithmtokenintheinjectorweconfigured.So,ifwewanttogetaninstanceoftheCollectionclassusinginjector.get(Collection),we’llgetaruntimeerror.ThismeansthatifwewanttogetaninstanceoftheCollectionclassusingtheDImechanismoftheframework,wemustregisteraproviderfortheSortingAlgorithmtoken,althoughwecanfallbacktothedefaultsortingalgorithm’simplementation.

Angular2providesasolutiontothisproblemwiththe@Optionaldecorator.

Thisishowwecanapproachtheproblemusingthe@Optionaldecoratorprovidedbytheframework:

//ch5/ts/decorators/optional.ts

@Injectable()

classCollectionextendsBaseCollection{

privatesort:SortingAlgorithm;

constructor(@Optional()sort:SortingAlgorithm){

super();

this.sort=sort||this.getDefaultSort();

}

}

Intheprecedingsnippet,wedeclaredthesortdependencyasoptional,whichmeansthatifAngular2doesn’tfindanyproviderforitstoken,itwillpassthenullvalue.

UsingmultiprovidersMultiprovidersareanothernewconceptbroughttotheAngular2DImechanism.Theyallowustoassociatemultipleproviderswiththesametoken.Thiscanbequiteusefulifwe’redevelopingathird-partylibrarythatcomeswithsomedefaultimplementationsofdifferentservices,butyouwanttoallowtheuserstoextenditwithcustomones.TheyarealsoexclusivelyusedtodeclaremultiplevalidationsoverasinglecontrolintheAngular2

Page 265: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

formmodule.WewillexplainthismoduleinChapter6,WorkingwiththeAngular2RouterandForms,andChapter7,ExplainingPipesandCommunicatingwithRESTfulServices.

AnothersampleofanapplicableusecaseofmultiprovidersiswhatAngular2usesforeventmanagementintheirWebWorkersimplementation.Theycreatemultiprovidersforeventmanagementplugins.Eachoftheprovidersreturnsadifferentstrategy,whichsupportsadifferentsetofevents(touchevents,keyboardevents,andsoon).Onceagiveneventoccurs,theycanchoosetheappropriatepluginthathandlesit.

Let’stakealookatanexamplethatillustratesthetypicalusageofmultiproviders:

//ch5/ts/configuring-providers/multi-providers.ts

constVALIDATOR=newOpaqueToken('validator');

interfaceEmployeeValidator{

(person:Employee):boolean;

}

classEmployee{...}

letinjector=Injector.resolveAndCreate([

provide(VALIDATOR,{multi:true,

useValue:(person:Employee)=>{

if(!person.name){

return'Thenameisrequired';

}

}

}),

provide(VALIDATOR,{multi:true,

useValue:(person:Employee)=>{

if(!person.name||person.name.length<1){

return'Thenameshouldbemorethan1symbollong';

}

}

}),

Employee

]);

Intheprecedingsnippet,wedeclaredaconstantcalledVALIDATORwithanewinstanceofOpaqueToken.Wealsocreatedaninjectorwhereweregisteredthreeproviders—twoofthemareusedasvaluefunctionsthat,basedondifferentcriteria,validateinstancesoftheclassEmployee.ThesefunctionsareofthetypeEmployeeValidator.

InordertodeclarethatwewanttheinjectortopassalltheregisteredvalidatorstotheconstructoroftheclassEmployee,weneedtousethefollowingconstructordefinition:

classEmployee{

name:string;

constructor(@Inject(VALIDATOR)privatevalidators:EmployeeValidator[])

{}

validate(){

returnthis.validators

.map(v=>v(this))

Page 266: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

.filter(value=>!!value);

}

}

Intheprecedingexample,wedeclaredaclassEmployeethatacceptsasingledependency—anarrayofEmployeeValidators.Inthemethodvalidate,weappliedtheindividualvalidatorsoverthecurrentclassinstanceandfilteredtheresultsinordertogetonlytheonesthathavereturnedanerrormessage.

NoticethattheconstructorargumentvalidatorsisoftheEmployeeValidator[]type.Sincewecan’tusethetype“arrayofobjects”asatokenforaprovider,becauseitisnotavalidtypereference,weneedtousethe@Injectparameterdecorator.

Page 267: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingDIwithcomponentsanddirectivesInChapter4,GettingStartedwithAngular2ComponentsandDirectives,whenwedevelopedourfirstAngular2directive,wesawhowwecantakeadvantageoftheDImechanismtoinjectservicesintoourUI-relatedcomponents(thatis,directivesandcomponents).

Let’stakeaquicklookatwhatwedidearlier,butfromaDIperspective:

//ch4/ts/tooltip/app.ts

//...

@Directive(...)

exportclassTooltip{

@Input()

saTooltip:string;

constructor(privateel:ElementRef,privateoverlay:Overlay){

this.overlay.attach(el.nativeElement);

}

//...

}

@Component({

//...

providers:[Overlay],

directives:[Tooltip]

})

classApp{}

Mostofthecodefromtheearlierimplementationisomittedbecauseitisnotdirectlyrelatedtoourcurrentfocus.

NotethattheconstructorofTooltipacceptstwodependencies:

AninstanceoftheElementRefclass.AninstanceoftheOverlayclass.

Thetypesofdependenciesarethetokensassociatedwiththeirproviders,andthecorrespondingvaluesfromtheprovidersaregoingtobeinjectedwiththeDImechanismofAngular2.

AlthoughthedeclarationofthedependenciesoftheTooltipclasslooksexactlythesameaswhatwedidintheprevioussections,there’sneitheranyexplicitconfigurationnoranyinstantiationofaninjector.

Page 268: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

IntroducingtheelementinjectorsUnderthehood,Angularwillcreateinjectorsforallthedirectivesandcomponents,andaddadefaultsetofproviderstoit.Thisistheso-calledelementinjectorandissomethingtheframeworktakescareofitself.Theinjectorsassociatedwiththecomponentsarecalledhostinjectors.OneoftheprovidersineachdirectiveandcomponentinjectorisassociatedwiththeElementReftoken;itwillreturnareferencetothehostelementofthedirective.ButwhereistheproviderfortheOverlayclassdeclared?Let’stakealookattheimplementationofthetop-levelcomponent:

@Component({

//...

providers:[Overlay],

directives:[Tooltip]})

classApp{}

WeconfiguredtheelementinjectorfortheAppcomponentbydeclaringtheproviderspropertyinsideofthe@Componentdecorator.Atthispoint,theregisteredprovidersaregoingtobevisiblebythedirectiveorthecomponentassociatedwiththecorrespondingelementinjectorandthecomponent’sentirecomponentsubtree,unlessitisoverriddensomewhereinthehierarchy.

DeclaringprovidersfortheelementinjectorsHavingthedeclarationofalltheprovidersinthesameplacemightbequiteinconvenient.Forexample,imaginewe’redevelopingalarge-scaleapplicationthathashundredsofcomponentsdependingonthousandsofservices.Inthiscase,configuringalltheprovidersintherootcomponentisnotapracticalsolution.Therewillbenamecollisionswhentwoormoreprovidersareassociatedtothesametoken.Theconfigurationwillbehugeanditwillbehardtotracewherethedifferenttokensneedtobeinjected.

Aswementioned,Angular2’s@Directive(andrespectively@Component)decoratorallowsustointroducedirective-specificprovidersusingtheprovidersproperty.Hereishowwecanapproachthis:

@Directive({

selector:'[saTooltip]',

providers:[OverlayMock]

})

exportclassTooltip{

@Input()

saTooltip:string;

constructor(privateel:ElementRef,privateoverlay:Overlay){

this.overlay.attach(el.nativeElement);

}

//...

}

//...

Page 269: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

bootstrap(App);

TheprecedingexampleoverridestheproviderfortheOverlaytokenintheTooltipdirective’sdeclaration.Thisway,AngularwillinjectaninstanceofOverlayMockinsteadofOverlayduringtheinstantiationofthetooltip.

Abetterwaytooverridetheproviderisusingthebootstrapfunction.Wecandothefollowing:

bootstrap(AppMock,[provide(Overlay,{

useClass:OverlayMock

})]);

Intheprecedingbootstrapcall,weprovidedadifferenttop-levelcomponentandproviderfortheOverlayservicethatwillreturnaninstanceoftheOverlayMockclass.Thisway,wecantesttheTooltipdirectiveignoringtheimplementationofOverlay.

ExploringDIwithcomponentsSincecomponentsaregenerallydirectiveswithviews,everythingwe’veseensofarregardinghowtheDImechanismworkswithdirectivesisvalidforcomponentsaswell.However,becauseoftheextrafeaturesthatthecomponentsprovide,we’reallowedtohavefurthercontrolovertheirproviders.

Aswesaid,theinjectorassociatedwitheachcomponentwillbemarkedasahostinjector.There’saparameterdecoratorcalled@Host,whichallowsustoretrieveagivendependencyfromanyinjectoruntilitreachestheclosesthostinjector.Thismeansthatbyusingthe@Hostdecoratorinadirective,wecandeclarethatwewanttoretrievethegivendependencyfromthecurrentinjectororanyparentinjectoruntilwereachtheinjectoroftheclosestparentcomponent.

TheviewProviderspropertyaddedtothe@Componentdecoratorisinchargeofachievingevenmorecontrol.

viewProvidersversusprovidersLet’stakealookatanexampleofacomponentcalledMarkdownPanel.Thiscomponentwillbeusedinthefollowingway:

<markdown-panel>

<panel-title>#Title</pane-title>

<panel-content>

#Contentofthepanel

*Firstpoint

*Secondpoint

</panel-content>

</markdown-panel>

ThecontentofeachsectionofthepanelwillbetranslatedfromthemarkdowntotheHTML.WecandelegatethisfunctionalitytoaservicecalledMarkdown:

import*asmarkdownfrom'markdown';

classMarkdown{

toHTML(md){

Page 270: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

returnmarkdown.toHTML(md);

}

}

TheMarkdownservicewrapsthemarkdownmoduleinordertomakeitinjectablethroughtheDImechanism.

Nowlet’simplementMarkdownPanel.

Inthefollowingsnippet,wecanfindalltheimportantdetailsfromthecomponent’simplementation:

//ch5/ts/directives/app.ts

@Component({

selector:'markdown-panel',

viewProviders:[Markdown],

styles:[...],

template:`

<divclass="panel">

<divclass="panel-title">

<ng-contentselect="panel-title"></ng-content>

</div>

<divclass="panel-content">

<ng-contentselect="panel-content"></ng-content>

</div>

</div>`

})

classMarkdownPanel{

constructor(privateel:ElementRef,privatemd:Markdown){}

ngAfterContentInit(){

letel=this.el.nativeElement;

lettitle=el.querySelector('panel-title');

letcontent=el.querySelector('panel-content');

title.innerHTML=this.md.toHTML(title.innerHTML);

content.innerHTML=this.md.toHTML(content.innerHTML);

}

}

Weusedthemarkdown-panelselectorandsettheviewProvidersproperty.Inthiscase,there’sonlyasingleviewprovider:theonefortheMarkdownservice.Bysettingthisproperty,wedeclaredthatalltheprovidersdeclaredinitwillbeaccessiblefromthecomponentitselfandallofitsviewchildren.

Now,let’ssupposewehaveacomponentcalledMarkdownButtonandwewanttoaddittoourtemplateinthefollowingway:

<markdown-panel>

<panel-title>###Smalltitle</panel-title>

<panel-content>

Somecode

</panel-content>

<markdown-button>*Clicktotoggle*</markdown-button>

</markdown-panel>

TheMarkdownservicewillnotbeaccessiblebytheMarkdownButtonusedbelowthepanel-contentelement;however,it’llbeaccessibleifweusethebuttoninthe

Page 271: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

component’stemplate:

@Component({

selector:'markdown-panel',

viewProviders:[Markdown],

directives:[MarkdownButton],

styles:[…],

template:`

<divclass="panel">

<markdown-button>*Clicktotoggle*</markdown-button>

<divclass="panel-title">

<ng-contentselect="panel-title"></ng-content>

</div>

<divclass="panel-content">

<ng-contentselect="panel-content"></ng-content>

</div>

</div>`

})

Ifweneedtheprovidertobevisibleinallthecontentandviewchildren,allweshoulddoischangethepropertynameoftheviewProviderspropertytoproviders.

Youcanfindthisexampleinthefileintheexamplesdirectoryatch5/ts/directives/app.ts.

Page 272: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingAngular’sDIwithES5WearealreadyproficientinusingthedependencyinjectionofAngular2withTypeScript!Asweknow,wearenotlimitedtoTypeScriptforthedevelopmentofAngular2applications;wecanalsouseES5,ES2015,andES2016(aswellasDart,butthatisoutofthescopeofthisbook).

Sofar,wedeclaredthedependenciesofthedifferentclassesintheirconstructorusingstandardTypeScripttypeannotations.Allsuchclassesaresupposedtobedecoratedwiththe@Injectabledecorator.Unfortunately,someoftheotherlanguagessupportedbyAngular2missafewofthesefeatures.Inthefollowingtable,wecanseethatES5doesn’tsupporttypeannotations,classes,anddecorators:

ES5 ES2015 ES2016

Classes No Yes Yes

Decorators No No Yes(noparameterdecorators)

Typeannotations No No No

Inthiscase,howwecantakeadvantageoftheDImechanismintheselanguages?Angular2providesaninternalJavaScriptDomainSpecificLanguage(DSL),whichallowsustotakeadvantageoftheentirefunctionalityoftheframeworkusingES5.

Now,let’stranslatetheMarkdownPanelexamplewetookalookatintheprevioussectionfromTypeScripttoES5.First,let’sstartwiththeMarkdownservice:

//ch5/es5/simple-example/app.js

varMarkdown=ng.core.Class({

constructor:function(){},

toHTML:function(md){

returnmarkdown.toHTML(md);

}

});

WedefinedavariablecalledMarkdownandsetitsvaluetothereturnedresultfromtheinvocationofng.core.Class.ThisconstructallowsustoemulateES2015classesusingES5.Theargumentoftheng.core.Classmethodisanobjectliteral,whichmusthavethedefinitionofaconstructorfunction.Asaresult,ng.core.ClasswillreturnaJavaScriptconstructorfunctionwiththebodyofconstructorfromtheobjectliteral.Alltheothermethodsdefinedwithintheboundariesofthepassedparameterwillbeaddedtothefunction’sprototype.

Oneproblemissolved:wecannowemulateclassesinES5;therearetwomoreproblemsleft!

Now,let’stakealookathowwecandefinetheMarkdownPanelcomponent:

//ch5/es5/simple-example/app.js

Page 273: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

varMarkdownPanel=ng.core.Component({

selector:'markdown-panel',

viewProviders:[Markdown],

styles:[...],

template:'...'

})

.Class({

constructor:[Markdown,ng.core.ElementRef,function(md,el){

this.md=md;

this.el=el;

}],

ngAfterContentInit:function(){

}

});

FromChapter4,GettingStartedwithAngular2ComponentsandDirectives,wearealreadyfamiliarwiththeES5syntaxusedtodefinecomponents.Now,let’stakealookattheconstructorfunctionofMarkdownPanelinordertomakesurehowwecandeclarethedependenciesofourcomponentsandevenclassesingeneral.

Fromtheprecedingsnippet,wecannotethatthevalueoftheconstructorisnotafunctionthistime,butanarrayinstead.ThismightseemfamiliartoyoufromAngularJS1.x,whereweareabletodeclarethedependenciesofthegivenservicebylistingtheirnames:

Module.service('UserMapper',

['User','$http',function(User,$http){

//…

}]);

AlthoughthesyntaxinAngular2issimilar,itbringsalotofimprovements.Forinstance,we’renolongerlimitedtousingstringsforthedependencies’tokens.

Now,let’ssupposewewanttomaketheMarkdownserviceanoptionaldependency.Inthiscase,wecanapproachthisbypassinganarrayofdecorators:

.Class({

constructor:[[ng.core.Optional(),Markdown],

ng.core.ElementRef,function(md,el){

this.md=md;

this.el=el;

}],

ngAfterContentInit:function(){

}

});

Thisway,bynestingarrays,wecanapplyasequenceofdecorators:[[ng.core.Optional(),ng.core.Self(),Markdown],...].Inthisexample,the@Optionaland@Selfdecoratorswilladdtheassociatedmetadatatotheclassinthespecifiedorder.

AlthoughusingES5makesourbuildsimplerandallowsustoskiptheintermediatestepof

Page 274: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

transpilation,whichcanbetempting,Google’srecommendationistotakeadvantageofstatictypingusingTypeScript.Thisway,wehaveamuchclearersyntax,whichcarriesbettersemanticswithlesstypingandprovidesuswithgreattooling.

Page 275: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 276: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SummaryInthischapter,wecoveredtheDImechanismofAngular2.Webrieflydiscussedthepositivesofusingdependencyinjectioninourprojectsbyintroducingitinthecontextoftheframework.Thesecondstepinourjourneywashowtoinstantiateandconfigureinjectors;wealsoexplainedtheinjectors’hierarchyandthevisibilityoftheregisteredproviders.Inordertoenforceabetterseparationofconcerns,wementionedhowwecaninjectservicescarryingthebusinesslogicofourapplicationinourdirectivesandcomponents.ThelastpointwetookalookatwashowwecanusetheDImechanismwiththeES5syntax.

Inthenextchapter,we’llintroducethenewroutingmechanismoftheframework.We’llexplainhowwecanconfigurethecomponent-basedrouterandaddmultipleviewstoourapplication.Anotherimportanttopicwearegoingtocoveristhenewformmodule.Bybuildingasimpleapplication,wewilldemonstratehowwecancreateandmanageforms.

Page 277: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 278: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Chapter6.WorkingwiththeAngular2RouterandFormsBynow,we’realreadyfamiliarwiththecoreoftheframework.Weknowhowtodefinecomponentsanddirectivesinordertodeveloptheviewofourapplications.Wealsoknowhowtoencapsulatebusiness-relatedlogicintoservicesandwireeverythingtogetherwiththedependencyinjectionmechanismofAngular2.

Inthischapter,we’llexplainafewmoreconceptsthatwillhelpusbuildreal-lifeAngular2applications.Theyareasfollows:

Thecomponent-basedrouteroftheframework.UsingAngular2forms.Developingtemplate-drivenforms.Developingcustomformvalidators.

Let’sbegin!

Page 279: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Developingthe“Codersrepository”applicationIntheprocessofexplainingtheconceptsmentionedearlier,we’lldevelopasampleapplicationthatcontainsarepositoryofdevelopers.Beforewestartcoding,let’sexplainthestructureoftheapplication.

The“Codersrepository”willallowitsuserstoadddeveloperseitherbyfillingaformwithdetailsaboutthemorbyprovidingtheGitHubhandleforthedeveloperandimportinghisorherprofilefromGitHub.

NoteForthepurposeofthischapter,wewillstoreinformationonthedevelopersinmemory,whichmeansthatafterthepageisrefreshed,we’llloseallthestoredduringthesessiondata.

Theapplicationwillhavethefollowingviews:

Alistofallthedevelopers.Aviewthataddsorimportsnewdevelopers.Aviewthatshowsthegivendeveloper’sdetails.Thisviewhastwosubviews:

Basicdetails:ShowsthenameofthedeveloperandherorhisGitHubavatarifavailable.Advancedprofile:Showsallthedetailsknownforthedeveloper.

Theendresultofthehomepageoftheapplicationwilllookasfollows:

Fig.1

NoteInthischapter,wewillbuildonlyafewofthelistedviews.Therestoftheapplicationwill

Page 280: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

beexplainedinChapter7,ExplainingPipesandCommunicatingwithRESTfulServices.

Eachdeveloperwillbeaninstanceofthefollowingclass:

//ch6/ts/multi-page-template-driven/developer.ts

exportclassDeveloper{

publicid:number;

publicgithubHandle:string;

publicavatarUrl:string;

publicrealName:string;

publicemail:string;

publictechnology:string;

publicpopular:boolean;

}

AllthedeveloperswillresidewithintheDeveloperCollectionclass:

//ch6/ts/multi-page-template-driven/developer_collection.ts

classDeveloperCollection{

privatedevelopers:Developer[]=[];

getUserByGitHubHandle(username:string){

returnthis.developers

.filter(u=>u.githubHandle===username)

.pop();

}

getUserById(id:number){

returnthis.developers

.filter(u=>u.id===id)

.pop();

}

addDeveloper(dev:Developer){

this.developers.push(dev);

}

getAll(){

returnthis.developers;

}

}

Theclassesmentionedhereencapsulatequiteasimplelogicanddon’thaveanythingAngular2-specific,sowewon’tgetintoanydetails.

Now,let’scontinuewiththeimplementationbyexploringthenewrouter.

Page 281: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 282: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ExploringtheAngular2routerAswealreadyknow,inordertobootstrapanyAngular2application,weneedtodeveloparootcomponent.The“Codersrepository”applicationisnotanydifferent;theonlyadditioninthisspecificcaseisthatwewillhavemultiplepagesthatneedtobeconnectedtogetherwiththeAngular2router.

Let’sstartwiththeimportsrequiredfortherouter’sconfigurationanddefinetherootcomponentrightafterthis:

//ch6/ts/step-0/app.ts

import{

ROUTER_DIRECTIVES,

ROUTER_PROVIDERS,

Route,

Redirect,

RouteConfig,

LocationStrategy,

HashLocationStrategy

}from'angular2/router';

Intheprecedingsnippet,weimportedacoupleofthingsdirectlyfromtheAngular2routermodule,whichisexternalizedoutsidetheframework’score.

WithROUTER_DIRECTIVES,therouterprovidesasetofcommonlyuseddirectivesthatwecanaddtothelistofusedonesbytherootcomponent.Thisway,wewillbeabletousetheminthetemplateslater.

TheimportROUTE_PROVIDERScontainsasetofrouter-relatedproviders,suchasoneforinjectingtheRouteParamstokenintothecomponents’constructors.

TheRouteParamstokenprovidesanaccesstoparametersfromtheroute’sURLinordertoparametrizethelogicassociatedwithagivenpage.We’lldemonstrateatypicalusecaseofthisproviderlater.

TheimportLocationStrategyclassisanabstractclassthatdefinesthecommonlogicbetweenHashLocationStrategy(usedforhash-basedrouting)andPathLocationStrategy(usedforHTML5-basedroutingbytakingadvantageofthehistoryAPI).

NoteHashLocationStrategydoesnotsupportserver-siderendering.Thisisduetothefactthatthehashofthepagedoesnotgetsenttotheserver,soitcannotfindoutthecomponentassociatedwiththegivenpage.AllmodernbrowsersexceptIE9supporttheHTML5historyAPI.Youcanfindmoreaboutserver-siderenderinginthelastchapterofthebook.

Thelastimportswedidn’ttakealookatareRouteConfig,whichisadecoratorthatallowsustodefinetheroutesassociatedwithagivencomponent;andRouteandRedirect,whichrespectivelyallowustodefinetheindividualroutesandredirects.WithRouteConfig,wecandefineahierarchyofroutes,whichmeansthattherouterofAngular

Page 283: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

2supportsnestedroutingoutoftheboxunlikeitspredecessorinAngularJS1.x.

Page 284: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningtherootcomponentandbootstrappingtheapplicationNow,let’sdefinearootcomponentandconfiguretheapplication’sinitialbootstrap:

//ch6/ts/step-0/app.ts

@Component({

selector:'app',

template:`…`,

providers:[DeveloperCollection],

directives:[ROUTER_DIRECTIVES]

})

@RouteConfig([…])

classApp{}

bootstrap(…);

Intheprecedingsnippet,youcannoticeasyntaxwe’realreadyfamiliarwithfromChapter4,GettingStartedwithAngular2ComponentsandDirectivesandChapter5,DependencyInjectioninAngular2.Wedefinedacomponentwithanappselector,templatethatwe’regoingtotakealookatlater,andsetsofprovidersanddirectives.

TheAppcomponentusesasingleprovidercalledDeveloperCollection.Thisistheclassthatcontainsallthedevelopersstoredbytheapplication.YoucannoticethatweaddedROUTER_DIRECTIVES;itcontainsanarrayofallthedirectivesdefinedwithintheAngular’srouter.Someofthedirectiveswithinthisarrayallowustolinktotheotherroutesdefinedwithinthe@RouteConfigdecorator(therouterLinkdirective)anddeclaretheplacewherethecomponentsassociatedwiththedifferentroutesshouldberendered(router-outlet).We’llexplainhowwecanusethemlaterinthissection.

Nowlet’stakealookatthecallofthebootstrapfunction:

bootstrap(App,[

ROUTER_PROVIDERS,

provide(LocationStrategy,{useClass:HashLocationStrategy})

)]);

Asthefirstargumentofbootstrap,wepasstherootcomponentoftheapplicationasusual.Thesecondargumentisalistofprovidersthatwillbeaccessiblebytheentireapplication.Tothesetofproviders,weaddROUTER_PROVIDERSandwealsoconfiguretheproviderfortheLocationStrategytoken.ThedefaultLocationStrategytoken,whichAngular2uses,isPathLocationStrategy(thatis,theHTML5-basedone).However,inthiscase,wearegoingtousethehash-basedone.

Thetwobiggestadvantagesofthedefaultlocationstrategyarethatitissupportedbytheserver-renderingmoduleofAngular2,andtheapplication’sURLlooksmorenaturaltotheenduser(there’sno#used).Ontheotherhand,incaseweusePathLocationStrategy,wemayneedtoconfigureourapplicationserver,inordertohandletheroutesproperly.

Page 285: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingPathLocationStrategyIfwewanttousePathLocationStrategy,wemayneedtoprovideAPP_BASE_HREF.Forinstance,inourcase,thebootstrapconfigurationshouldlookasfollows:

import{APP_BASE_HREF}from'angular2/router';

//...

bootstrap(App,[

ROUTER_PROVIDERS,

//Thefollowinglineisoptional,sinceit's

//thedefaultvaluefortheLocationStrategytoken

provide(LocationStrategy,{useClass:PathLocationStrategy}),

provide(APP_BASE_HREF,{

useValue:'/dist/dev/ch6/ts/multi-page-template-driven/'

}

)]);

Bydefault,thevalueassociatedwiththeAPP_BASE_HREFtokenis/;itrepresentsthebasepathnameinsideoftheapplication.Forinstance,inourcase,the“Codersrepository”willbelocatedunderthe/ch6/ts/multi-page-template-driven/directory(thatis,http://localhost:5555/dist/dev/ch6/ts/multi-page-template-driven/).

Page 286: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Configuringrouteswith@RouteConfigAsthenextstep,let’stakealookattheroute’sdeclarationplacedinthe@RouteConfigdecorator:

//ch6/ts/step-0/app.ts

@Component(…)

@RouteConfig([

newRoute({component:Home,name:'Home',path:'/'}),

newRoute({

component:AddDeveloper,

name:'AddDeveloper',

path:'/dev-add'

}),

//…

newRedirect({

path:'/add-dev',

redirectTo:['/dev-add']

})

])

classApp{}

Astheprecedingsnippetshows,the@RouteConfigdecoratoracceptsanarrayofroutesasanargument.Intheexample,wedefinedtwotypesofroutes:usingtheclassesRouteandRedirect.Theyareusedrespectivelytodefinetheroutesandredirectsintheapplication.

Eachroutemustdefinethefollowingproperties:

component:Thecomponentassociatedwiththegivenroute.name:Thenameoftherouteusedforreferencingitinthetemplates.path:Thepathtobeusedfortheroute.Itwillbevisibleinthebrowser’slocationbar.

NoteTheRouteclassalsosupportsadatapropertywhosevaluecanbeinjectedintheconstructorofitsassociatedcomponentbyusingtheRouteDatatoken.Asampleusecaseofthedatapropertycouldbeifwewanttoinjectdifferentconfigurationobjectsbasedonthetypeoftheparentcomponentthatcontainsthe@RouteConfigdeclaration.

Ontheotherhand,theredirectcontainsonlytwoproperties:

path:Thepathtobeusedfortheredirection.redirectTo:Thepaththeuserisredirectedto.

Inthepreviousexample,wedeclaredthatwewantthepageopenedbytheuserwiththepath/add-devtoberedirectedto['/dev-add'].

Now,inordertomakeeverythingwork,weneedtodefinetheAddDeveloperandHomecomponents,[email protected],we’regoingtoprovideabasicimplementationthatwe’llincrementallyextendovertimealongthechapter.Inch6/ts/step-0,createafilecalledhome.tsandenterthefollowingcontent:

Page 287: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

import{Component}from'angular2/core';

@Component({

selector:'home',

template:`Home`

})

exportclassHome{}

DonotforgettoimporttheHomecomponentinapp.ts.Now,openthefilecalledadd_developer.tsandenterthefollowingcontentinit:

import{Component}from'angular2/core';

@Component({

selector:'dev-add',

template:`Adddeveloper`

})

exportclassAddDeveloper{}

Page 288: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingrouterLinkandrouter-outletWehavetheroute’sdeclarationandallthecomponentsassociatedwiththeindividualroutes.TheonlythingleftistodefinethetemplateoftherootAppcomponentinordertolinkeverythingtogether.

Addthefollowingcontenttothetemplatepropertyinsidethe@Componentdecoratorinch6/ts/step-0/app.ts:

@Component({

//…

template:`

<navclass="navbarnavbar-default">

<ulclass="navnavbar-nav">

<li><a[routerLink]="['/Home']">Home</a></li>

<li><a[routerLink]="['/AddDeveloper']">Adddeveloper</a></li>

</ul>

</nav>

<router-outlet></router-outlet>

`,

//…

})

InthetemplateabovetherearetwoAngular2-specificdirectives:

routerLink:Thisallowsustoaddalinktoaspecificroute.router-outlet:Thisdefinesthecontainerwherethecomponentsassociatedwiththecurrentlyselectedrouteneedtoberendered.

Let’stakealookattherouterLinkdirective.Asvalueitacceptsanarrayofroutenamesandparameters.Inourcaseweprovideonlyasingleroutenameprefixedwithslash(sincethisrouteisonrootlevel).NoticethattheroutenameusedbyrouterLinkisdeclaredbythenamepropertyoftheroutedeclarationinside@RouteConfig.Laterinthischapterwe’llseehowwecanlinktonestedroutesandpassrouteparameters.

ThisdirectiveallowsustodeclarelinksindependentlyfromLocationStrategythatwehaveconfigured.Forinstance,imagineweareusingHashLocationStrategy;thismeansthatweneedtoprefixalltheroutesinourtemplateswith#.IncaseweswitchtoPathLocationStrategy,we’llneedtoremoveallthehashprefixes.AnotherhugebenefitofrouterLinkisthatitusestheHTML5historypushAPItransparentlytous,whichsavesusfromalotofboilerplates.

Thenextdirectivefromtheprevioustemplatethatisnewtousisrouter-outlet.Ithassimilarresponsibilitytotheng-viewdirectiveinAngularJS1.x.Basically,theybothhavethesamerole:topointoutwherethetargetcomponentshouldberendered.Thismeansthataccordingtothedefinition,whentheusernavigatesto/,theHomecomponentwillberenderedatthepositionpointedoutbyrouter-outlet,samefortheAddDevelopercomponentoncetheusernavigatesto/dev-add.

Nowwehavethesetworoutesupandrunning!Openhttp://localhost:5555/dist/dev/ch6/ts/step-0/andyoushouldseethefollowing

Page 289: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

screenshot:

Fig.2

Ifyoudon’t,justtakealookatch6/ts/step-1thatcontainstheendresult.

Page 290: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Lazy-loadingwithAsyncRouteAngularJS1.xmodulesallowustogrouptogetherlogicallyrelatedunitsintheapplication.However,bydefault,theyneedtobeavailableduringtheinitialapplication’sbootstrapanddonotallowdeferredloading.Thisrequiresdownloadingtheentirecodebaseoftheapplicationduringtheinitialpageloadthat,incaseoflargesingle-pageapps,canbeanunacceptableperformancehit.

Inaperfectscenario,wewouldwanttoloadonlythecodeassociatedwiththepagetheuseriscurrentlyviewing,ortoprefetchbundledmodulesbasedonheuristicsrelatedtotheuser’sbehavior,whichisoutofthescopeofthisbook.Forinstance,opentheapplicationfromthefirststepofourexample:http://localhost:5555/dist/dev/ch6/ts/step-1/.Oncetheuserisat/,weonlyneedtheHomecomponenttobeavailable,andonceheorshenavigatesto/dev-add,wewanttoloadtheAddDevelopercomponent.

Let’sinspectwhatisactuallygoingoninChromeDevTools:

Fig.3

Wecannoticethatduringtheinitialpageload,wedownloadedthecomponentsassociatedwithalltheroutes,evenAddDeveloperthatisnotrequired.Thishappensbecauseinapp.ts,weexplicitlyrequireboththeHomeandtheAddDevelopercomponentsandusetheminthe@RouteConfigdeclaration.

Inthisspecificcase,loadingboththecomponentsmaynotseemlikeabigproblem,becauseatthisstep,theyareprettysimpleanddonothaveanydependencies.However,inreal-lifeapplications,theywillhaveimportsofotherdirectives,components,pipes,services,oreventhird-partylibraries.Onceanyofthecomponentsisrequired,itsentire

Page 291: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

dependencygraphwillbedownloaded,evenifthecomponentisnotneededatthatpoint.

TherouterofAngular2comeswithasolutiontothisproblem.AllweneedtodoisimporttheAsyncRouteclassfromtheangular2/routermoduleanduseitinside@RouteConfiginsteadofusingRoute:

//ch6/ts/step-1-async/app.ts

import{AsyncRoute}from'angular2/router';

@Component(…)

@RouteConfig([

newAsyncRoute({

loader:()=>

System.import('./home')

.then(m=>m.Home),

name:'Home',

path:'/'

}),

newAsyncRoute({

loader:()=>

System.import('./add_developer')

.then(m=>m.AddDeveloper),

name:'AddDeveloper',

path:'/dev-add'

}),

newRedirect({path:'/add-dev',redirectTo:['/dev-add']})

])

classApp{}

TheconstructoroftheAsyncRouteclassacceptsasanargumentanobjectwiththefollowingproperties:

loader:Afunctionthatreturnsapromisethatneedstoberesolvedwiththecomponentassociatedwiththegivenroute.name:Thenameoftheroutethatcanbeusedtorefertoitinthetemplates(usually,insideoftherouterLinkdirective).path:Thepathoftheroute.

Oncetheusernavigatestoaroutethatmatchesanyoftheasyncroutes’definitionsinthe@RouteConfigdecorator,itsassociatedloaderwillbeinvoked.Whenthepromisereturnedbytheloaderisresolvedwithavalueofthetargetcomponent,thecomponentwillbecachedandrendered.Nexttimetheusernavigatestothesameroute,thecachedcomponentwillbeused,sotheroutingmodulewon’tdownloadthesamecomponenttwice.

NoteNoticethattheprecedingexampleusesSystem,however,Angular’sAsyncRouteimplementationisnotcoupledtoanyparticularmoduleloader.Thesameresultcouldbeachieved,forinstance,withrequire.js.

Page 292: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 293: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingAngular2formsNowlet’scontinuewiththeimplementationoftheapplication.Forthenextstep,we’llworkontheAddDeveloperandHomecomponents.Youcancontinueyourimplementationbyextendingwhatyoucurrentlyhaveinch6/ts/step-0,orifyouhaven’treachedstep1yet,youcankeepworkingonthefilesinch6/ts/step-1.

Angular2offerstwowaystodevelopformswithvalidation:

Atemplate-drivenapproach:ProvidesadeclarativeAPIwherewedeclarethevalidationsintothetemplateofthecomponent.Amodel-drivenapproach:ProvidesanimperativeAPIwithFormBuilder.

Inthenextchapter,we’llexploreboth.Let’sstartwiththetemplate-drivenapproach.

Page 294: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Developingtemplate-drivenformsFormsareessentialforeachCRUD(CreateRetrieveUpdateandDelete)application.Inourcase,wewanttobuildaformforenteringthedetailsofthedeveloperswewanttostore.

Bytheendofthissection,we’llhaveaformthatallowsustoentertherealnameofagivendeveloper,toaddhisorherpreferredtechnology,enterane-mail,anddeclarewhethersheorheispopularinthecommunityornotyet.Theendresultwilllookasfollows:

Fig.4

Addthefollowingimportstoadd_developer.ts:

import{

FORM_DIRECTIVES,

FORM_PROVIDERS

}from'angular2/common;

ThenextthingweneedtodoisaddFORM_DIRECTIVEStothelistofdirectivesusedbytheAddDevelopercomponent.TheFORM_DIRECTIVESdirectivescontainsasetofpredefineddirectivesformanagingAngular2forms,suchastheformandngModeldirectives.

TheFORM_PROVIDERSisanarraywithapredefinedsetofprovidersthatwecanuseforinjectingthevaluesassociatedwiththeirtokensintheclassesofourapplication.

NowupdatetheAddDeveloperimplementationtothefollowing:

@Component({

Page 295: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

selector:'dev-add',

templateUrl:'./add_developer.html',

styles:[…],

directives:[FORM_DIRECTIVES],

providers:[FORM_PROVIDERS]

})

exportclassAddDeveloper{

developer=newDeveloper();

errorMessage:string;

successMessage:string;

submitted=false;

technologies:string[]=[

'JavaScript',

'C',

'C#',

'Clojure'

];

constructor(privatedevelopers:DeveloperCollection){}

addDeveloper(){}

}

Thedeveloperpropertycontainstheinformationassociatedwiththecurrentdeveloperthatwe’readdingwiththeform.Thelasttwoproperties,errorMessageandsuccessMessage,aregoingtobeusedrespectivelyfordisplayingthecurrentform’serrororsuccessmessagesoncethedeveloperhasbeensuccessfullyaddedtothedeveloperscollection,oranerrorhasoccurred.

Page 296: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Diggingintothetemplate-drivenform’smarkupAsthenextstep,let’screatethetemplateoftheAddDevelopercomponent(step-1/add_developer.html).Addthefollowingcontenttothefile:

<span*ngIf="errorMessage"

class="alertalert-danger">{{errorMessage}}</span>

<span*ngIf="successMessage"

class="alertalert-success">{{successMessage}}</span>

Thesetwoelementsareintendedtodisplaytheerrorandsuccessmessageswhenaddinganewdeveloper.TheyaregoingtobevisiblewhenerrorMessageandsuccessMessagerespectivelyhavenon-falsyvalues(thatis,somethingdifferentfromtheemptystring,false,undefined,0,NaN,ornull).

Nowlet’sdeveloptheactualform:

<form#f="ngForm"(ngSubmit)="addDeveloper()"

class="formcol-md-4"[hidden]="submitted">

<divclass="form-group">

<labelclass="control-label"

for="realNameInput">Realname</label>

<div>

<inputid="realNameInput"class="form-control"

type="text"ngControl="realName"required

[(ngModel)]="developer.realName">

</div>

</div>

<buttonclass="btnbtn-default"

type="submit"[disabled]="!f.form.valid">Add</button>

<!--MORECODETOBEADDED-->

</form>

WedeclareanewformusingtheHTMLformtag.OnceAngular2findssuchtagsinatemplatewithanincludedformdirectiveintheparentcomponent,itwillautomaticallyenhanceitsfunctionalityinordertobeusedasanAngularform.OncetheformisprocessedbyAngular,wecanapplyformvalidationanddata-bindings.Afterthis,using#f="ngForm",wewilldefinealocalvariableforthetemplatecalledf,whichallowsustoreferencetothecurrentform.Thelastthingleftfromtheformelementisthesubmiteventhandler.Weuseasyntaxthatwe’realreadyfamiliarwith(ngSubmit)="expr",whereinthiscase,thevalueoftheexpressionisthecalloftheaddDevelopermethodattachedtothecomponent’scontroller.

Now,let’stakealookatthedivelementwithclassnamecontrol-group.

NoteNotethatthisisnotanAngular-specificclass;itisaCSSclassdefinedbyBootstrapthatweuseinordertoprovideabetterlookandfeeltotheform.

Insideofit,wecanfindalabelelementthatdoesn’thaveanyAngular-specificmarkupandaninputelementthatallowsustosettherealnameofthecurrentdeveloper.WesetthecontroltobeofatypetextanddeclareitsidentifiertoequalrealNameInput.The

Page 297: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

requiredattributeisdefinedbytheHTML5specificationandisusedforvalidation.Byusingitontheelement,wedeclarethatitisrequiredforthiselementtohaveavalue.AlthoughthisattributeisnotAngular-specificusingthengControlattribute,Angularwillextendthesemanticsoftherequiredattributebyincludingvalidationbehavior.ThisbehaviorincludessettingspecificCSSclassesonthecontrolwhenitsstatuschangesandmanagingitsstatethattheframeworkkeepsinternally.

ThengControldirectiveisaselectoroftheNgControlNamedirective.Itenhancesthebehavioroftheformcontrolsbyrunningvalidationoverthemforthechangeoftheirvalues,andapplyingspecificclassesduringthecontrols’lifecycle.YoumightbefamiliarwiththisfromAngularJS1.xwheretheformcontrolsaredecoratedwiththeng-pristine,ng-invalid,andng-validclasses,andsoon,inspecificphasesoftheirlifecycle.

ThefollowingtablesummarizestheCSSclassesthattheframeworkaddstotheformcontrolsduringtheirlifecycle:

Classes Description

ng-untouched Thecontrolhasn’tbeenvisited

ng-touched Thecontrolhasbeenvisited

ng-pristine Thecontrol’svaluehasn’tbeenchanged

ng-dirty Thecontrol’svaluehasbeenchanged

ng-valid Allthevalidatorsattachedtothecontrolhavereturnedtrue

ng-invalid Anyofthevalidatorsattachedtothecontrolhasafalsevalue

Accordingtothistable,wecandefinethatwewantalltheinputcontrolswithinvalidvaluetohavearedborderinthefollowingway:

input.ng-dirty.ng-invalid{

border:1pxsolidred;

}

TheexactsemanticsbehindtheprecedingCSSinthecontextofAngular2istousearedborderforalltheinputelementswhosevalueshavebeenchangedandareinvalidaccordingtothevalidatorsattachedtothem.

Now,let’sexplorehowwecanattachdifferentvalidationbehaviortoourcontrols.

Page 298: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Usingthebuilt-informvalidatorsWealreadysawthatwecanaltervalidationbehaviortoanycontrolbyusingtherequiredattribute.Angular2providestwomorebuilt-invalidators,asfollows:

minlength:Allowsustospecifytheminimumlengthofthevaluethatagivencontrolshouldhave.maxlength:Allowsustospecifythemaximumlengthofthevaluethatagivencontrolshouldhave.

ThesevalidatorsaredefinedwithAngular2directivesandcanbeusedinthefollowingway:

<inputid="realNameInput"class="form-control"

type="text"ngControl="realName"

minlength="2"

maxlength="30">

Thisway,wespecifythatwewantthevalueoftheinputtobebetween2and30characters.

Page 299: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningcustomcontrolvalidatorsAnotherdatapropertydefinedintheDeveloperclassistheemailfield.Let’saddaninputfieldforthisproperty.Abovethebuttonintheprecedingform,addthefollowingmarkup:

<divclass="form-group">

<labelclass="control-label"for="emailInput">Email</label>

<div>

<inputid="emailInput"

class="form-control"

type="text"ngControl="email"

[(ngModel)]="developer.email"/>

</div>

</div>

Wecanthinkofthe[(ngModel)]attributeasanalternativetotheng-modeldirectivefromAngularJS1.x.WewillexplainitindetailintheTwo-waydatabindingwithAngular2section.

AlthoughAngular2providesasetofpredefinedvalidators,theyarenotenoughforallthevariousformatsourdatacanlivein.Sometimes,we’llneedcustomvalidationlogicforourapplication-specificdata.Forinstance,inthiscase,wewanttodefineane-mailvalidator.Atypicalregularexpression,whichworksingeneralcases(butdoesnotcovertheentirespecificationthatdefinestheformatofthee-mailaddresses),looksasfollows:/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/.

Inch6/ts/step-1/add_developer.ts,defineafunctionthatacceptsaninstanceofAngular2controlasanargumentandreturnsnullifthecontrol’svalueisemptyormatchestheregularexpressionmentionedearlier,and{'invalidEmail':true}otherwise:

functionvalidateEmail(emailControl){

if(!emailControl.value||

/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-

9-.]+$/.test(emailControl.value)){

returnnull;

}else{

return{'invalidEmail':true};

}

}

Now,fromthemodulesangular2/commonandangular2/coreimportNG_VALIDATORSandDirective,andwrapthisvalidationfunctionwithinthefollowingdirective:

@Directive({

selector:'[email-input]',

providers:[provide(NG_VALIDATORS,{

useValue:validateEmail,multi:true

})]

})

classEmailValidator{}

Intheprecedingcode,wedefinedasinglemultiproviderforthetokenNG_VALIDATORS.

Page 300: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Onceweinjectthevalueassociatedwiththistoken,we’llgetanarraywithallthevalidatorsattachedtothegivencontrol(forreference,takealookatthesectionformultiprovidersinChapter5,DependencyInjectioninAngular2).

Theonlytwostepsleftinordertomakeourcustomvalidationworkaretofirstaddtheemail-inputattributetothee-mailcontrol:

<inputid="emailInput"

class="form-control"

email-input

type="text"ngControl="email"

[(ngModel)]="developer.email"/>

Next,toaddthedirectivetothelistusedbythecomponentAddDeveloperdirectives:

@Component({

selector:'dev-add',

templateUrl:'./add_developer.html',

styles:[`

input.ng-touched.ng-invalid{

border:1pxsolidred;

}

`],

directives:[FORM_DIRECTIVES,EmailValidator],

providers:[FORM_PROVIDERS]

})

classAddDeveloper{…}

NoteWe’reusinganexternaltemplatefortheAddDevelopercontrol.There’snoultimateanswertowhetheragiventemplateshouldbeexternalizedorinlinedwithinthecomponentwithtemplateUrlortemplate,respectively.Thebestpracticestatesthatweshouldinlinetheshorttemplatesandexternalizethelongerones,butthere’snospecificdefinitionastowhichtemplatesareconsideredshortandwhicharelong.Thedecisiononwhetherthetemplateshouldbeusedinlineorputintoanexternalfiledependsonthedeveloper’spersonalpreferencesorcommonconventionswithintheorganization.

Page 301: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingselectinputswithAngularAsthenextstep,weshouldallowtheuseroftheapplicationtoenterthetechnologyintowhichtheinputdeveloperhasthemostproficiency.Wecandefinealistoftechnologiesandshowthemintheformasaselectinput.

IntheAddDeveloperclass,addthetechnologiesproperty:

classAddDeveloper{

technologies:string[]=[

'JavaScript',

'C',

'C#',

'Clojure'

];

}

Nowinthetemplate,justabovethesubmitbutton,addthefollowingmarkup:

<divclass="form-group">

<labelclass="control-label"

for="technologyInput">Technology</label>

<div>

<selectclass="form-control"

ngControl="technology"required

[(ngModel)]="developer.technology">

<option*ngFor="#toftechnologies"

[value]="t">{{t}}</option>

</select>

</div>

</div>

Justlikefortheinputelementswedeclaredearlier,Angular2willaddthesameclassesdependingonthestateoftheselectinput.Inordertoshowredborderaroundtheselectelementwhenitsvalueisinvalid,weneedtoaltertheCSSrules:

@Component({

styles:[

`input.ng-touched.ng-invalid,

select.ng-touched.ng-invalid{

border:1pxsolidred;

}`

],

})

classAddDeveloper{…}

NoteNoticethatinliningallthestylesinourcomponents’declarationcouldbeabadpractice,becausethisway,theywon’tbereusable.Whatwecandoisextractallthecommonstylesacrossourcomponentsintoseparatefiles.The@Componentdecoratorhasapropertycalled

Page 302: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

styleUrlsoftypearraywherewecanaddareferencetotheextractedstylesusedbythegivencomponent.Thisway,wecaninlineonlythecomponent-specificstylesifrequired.

Rightafterthis,wewilldeclarethenameofthecontroltobeequalto“technology”usingngControl="technology".Byusingtherequiredattribute,wewilldeclarethattheuseroftheapplicationmustspecifythetechnologyintowhichthecurrentdeveloperisproficient.Let’sskipthe[(ngModel)]attributeforthelasttimeandseehowwecandefinetheselectelement’soptions.

Insidetheselectelement,wewilldefinethedifferentoptionsusing:

<option*ngFor="#toftechnologies"

[value]="t">{{t}}</option>

Thisisasyntaxwe’realreadyfamiliarwith.WewillsimplyiterateoverallthetechnologiesdefinedwithintheAddDeveloperclass,andforeachtechnology,wewillshowanoptionelementwithavalueofthetechnologyname.

Page 303: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingtheNgFormdirectiveWealreadymentionedthattheformdirectiveenhancestheHTML5form’sbehaviorbyaddingsomeadditionalAngular2-specificlogic.Now,let’stakeastepbackandtakealookattheformthatsurroundstheinputelements:

<form#f="ngForm"(ngSubmit)="addDeveloper()"

class="formcol-md-4"[hidden]="submitted">

</form>

Intheprecedingsnippet,wedefinedanewidentifiercalledf,whichreferencestotheform.Wecanthinkoftheformasacompositionofcontrols;wecanaccesstheindividualcontrolsthroughtheform’scontrolsproperty.Ontopofthis,theformhasthetouched,untouched,pristine,dirty,invalid,andvalidproperties,whichdependontheindividualcontrolsdefinedwithintheform.Forexample,ifnoneofthecontrolswithintheformhasbeentouched,thentheformitselfisgoingtobewiththestatusuntouched.However,ifanyofthecontrolsintheformhasbeentouchedatleastonce,theformwillbewiththestatustouchedaswell.Similarlytheformwillbevalidonlyifallitscontrolsarevalid.

Inordertoillustratetheusageoftheformelement,let’sdefineacomponentwiththeselectorcontrol-errors,whichshowsthecurrenterrorsforagivencontrol.Wecanuseitinthefollowingway:

<labelclass="control-label"for="realNameInput">Realname</label>

<div>

<inputid="realNameInput"class="form-control"type="text"

ngControl="realName"[(ngModel)]="developer.realName"

requiredmaxlength="50">

<control-errorscontrol="realName"

[errors]="{

'required':'Realnameisrequired',

'maxlength':'Themaximumlengthoftherealnameis50characters'

}"

/>

</div>

Noticethatwe’vealsoaddedthemaxlengthvalidatortotherealNamecontrol.

Thecontrol-errorselementhasthefollowingproperties:

control:Declaresthenameofthecontrolwewanttoshowerrorsfor.errors:Createsamappingbetweencontrolerrorandanerrormessage.

Nowaddthefollowingimportsinadd_developer.ts:

import{NgControl,NgForm}from'angular2/common';

import{Host}from'angular2/core';

Intheseimports,theNgControlclassistheabstractclassthatrepresentstheindividualformcomponents,NgFormrepresentstheAngularforms,andHostisaparameterdecoratorrelatedtothedependencyinjectionmechanism,whichwealreadycoveredinChapter5,DependencyInjectioninAngular2.

Page 304: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Hereisapartofthecomponent’sdefinition:

@Component({

template:'<div>{{currentError}}</div>',

selector:'control-errors',

inputs:['control','errors']

})

classControlErrors{

errors:Object;

control:string;

constructor(@Host()privateformDir:NgForm){}

getcurrentError(){…}

}

TheControlErrorscomponentdefinestwoinputs:control—thenameofthecontroldeclaredwiththengControldirective(thevalueofthengControlattribute)—anderrors—themappingbetweenanerrorandanerrormessage.Theycanbespecifiedrespectivelybythecontrolandtheerrorsattributesofthecontrol-errorselement.

Forinstance,ifwehavecontrol:

<inputtype="text"ngControl="foobar"required/>

Wecandeclareitsassociatedcontrol-errorscomponentbyusingthefollowing:

<control-errorscontrol="foobar"

[errors]="{

'required':'Thevalueoffoobarisrequired'

}"></control-errors>

InsideofthecurrentErrorgetter,intheprecedingsnippet,weneedtodothefollowingtwothings:

Findareferencetothecomponentdeclaredwiththecontrolattribute.Returntheerrormessageassociatedwithanyoftheerrorsthatmakethecurrentcontrolinvalid.

Hereisasnippetthatimplementsthisbehavior:

@Component(…)

classControlErrors{

getcurrentError(){

letcontrol=this.formDir.controls[this.control];

leterrorsMessages=[];

if(control&&control.touched){

errorsMessages=Object.keys(this.errors)

.map(k=>control.hasError(k)?this.errors[k]:null)

.filter(error=>!!error);

}

returnerrorsMessages.pop();

}

}

InthefirstlineoftheimplementationofcurrentError,wegetthetargetcontrolbyusingthecontrolspropertyoftheinjectedform.Itisofthetype{[key:string]:

Page 305: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

AbstractControl},wherethekeyisthenameofthecontrolwe’vedeclaredwiththengControldirective.Oncewehaveareferencetotheinstanceofthetargetcontrol,wecancheckwhetheritsstatusistouched(thatis,whetherithasbeenfocused),andifitis,wecanloopoveralltheerrorswithintheerrorspropertyoftheinstanceofControlError.Themapfunctionwillreturnanarraywitheitheranerrormessageoranullvalue.Theonlythingleftistofilterallthenullvaluesandgetonlytheerrormessages.Oncewegettheerrormessagesforeacherror,wewillreturnthelastonebypoppingitfromtheerrorMessagesarray.

Theendresultshouldlookasfollows:

Fig.5

IfyouexperienceanyproblemsduringtheimplementationoftheControlErrorscomponent,youcantakealookatitsimplementationatch6/ts/multi-page-template-driven/add_developer.ts.

ThehasErrormethodofeverycontrolacceptsasanargumentanerrormessageidentifier,whichisdefinedbythevalidator.Forinstance,intheprecedingexamplewherewedefinedthecustome-mailvalidator,wewillreturnthefollowingobjectliteralwhentheinputcontrolhasaninvalidvalue:{'invalidEmail':true}.IfweapplytheControlErrorscomponenttothee-mailcontrol,itsdeclarationshouldlookasfollows:

<control-errorscontrol="email"

[errors]="{'invalidEmail':'Invalidemailaddress'}"/>

Page 306: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 307: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Two-waydata-bindingwithAngular2OneofthemostfamousrumorsaboutAngular2wasthatthetwo-waydata-bindingfunctionalitywasremovedbecauseoftheenforcedunidirectionaldataflow.Thisisnotexactlytrue;theAngular2’sformmoduleimplementsadirectivewiththeselector[(ngModel)],whichallowsustoeasilyachievedata-bindingintwodirections—fromtheviewtothemodelandfromthemodeltotheview.

Let’stakealookatthefollowingsimplecomponent:

//ch6/ts/simple-two-way-data-binding/app.ts

import{Component}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

import{NgModel}from'angular2/common';

@Component({

selector:'app',

directives:[NgModel],

template:`

<inputtype="text"[(ngModel)]="name"/>

<div>{{name}}</div>

`,

})

classApp{

name:string;

}

bootstrap(App,[]);

Intheprecedingexample,weimportedthedirectiveNgModelfromtheangular2/commonpackage.Later,inthetemplate,wesettheattribute[(ngModel)]tothevaluename.

Atfirst,thesyntax[(ngModel)]mightseemalittlebitunusual.FromChapter4,GettingStartedwithAngular2ComponentsandDirectives,weknowthatthesyntax(eventName)isusedforbindingtoevents(oroutputs)triggeredbyagivencomponent.Ontheotherhand,weusethesyntax[propertyName]="foobar"toachieveone-waydata-bindingbysettingthevalueoftheproperty(orintheterminologyoftheAngular2components,theinput)withthenamepropertyNametotheresultoftheevaluationoftheexpressionfoobar.ThesyntaxNgModeljustcombinesbothinordertoachievedata-bindingintwodirections.That’swhywecanthinkofitmorelikeasyntaxsugar,ratherthananewconcept.OneofthemainadvantagesofthissyntaxcomparedtoAngularJS1.xisthatwecantellwhichbindingsareone-wayandwhicharetwo-wayonlybylookingatthetemplate.

NoteJustlike(click)hasitscanonicalsyntaxon-clickand[propertyName]hasbind-propertyName,thealternativesyntaxof[(ngModel)]isbindon-ngModel.

Ifyouopenhttp://localhost:5555/dist/dev/ch6/ts/simple-two-way-data-

Page 308: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

binding/,youwillseethefollowingresult:

Fig.6

Onceyouchangethevalueoftheinputbox,itwillautomaticallyupdatethefollowinglabel.

WealreadyusedtheNgModeldirectiveintheprecedingtemplates.Forexample,weboundtothedeveloper’se-mailusing:

<inputid="emailInput"

class="form-control"type="text"

ngControl="email"[(ngModel)]="developer.email"

email-input/>

Thisway,thevalueofthee-mailpropertyofthedeveloperobjectattachedtotheAddDevelopercomponent’sinstanceisgoingtobeupdatedoncewechangethevalueofthetextinput.

Page 309: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 310: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

StoringtheformdataLet’speekattheinterfaceoftheAddDevelopercomponent’scontrolleragain:

exportclassAddDeveloper{

submitted:false;

successMessage:string;

developer=newDeveloper();

//…

constructor(privatedevelopers:DeveloperCollection){}

addDeveloper(form){…}

}

IthasafieldofthetypeDeveloper,andwebindtheformcontrolstoitspropertiesusingtheNgModeldirective.TheclassalsohasamethodcalledaddDeveloper,whichisbeinginvokedonthesubmissionoftheform.Wedeclarethisbybindingtothesubmiteventusing:

<!--ch6/ts/multi-page-template-driven/add_developer.html-->

<form#f="form"(ngSubmit)="addDeveloper()"

class="formcol-md-4"[hidden]="submitted">

<buttonclass="btnbtn-default"

type="submit"[disabled]="!f.form.valid">Add</button>

</form>

Intheprecedingsnippet,wecannoticetwomorethings.Wegotareferencetotheformusing#f="ngForm"andweboundthedisabledpropertyofthebuttontotheexpression:!f.form.valid.WealreadydescribedtheNgFormcontrolintheprevioussection;itsvalidpropertywillhaveavaluetrueonceallthecontrolswithintheformhavevalidvalues.

Now,let’ssupposewe’veenteredvalidvaluesforalltheinputcontrolsintheform.Thismeansthatitssubmitbuttonwillbeenabled.OncewepressEnterorweclickontheAddbutton,theaddDevelopermethodwillbeinvoked.Thefollowingisasampleimplementationofthismethod:

classAddDeveloper{

//…

addDeveloper(){

this.developer.id=this.developers.getAll().length+1;

this.developers.addDeveloper(this.developer);

this.successMessage=`Developer${this.developer.realName}was

successfullyadded`;

this.submitted=true;

}

Initially,wesettheidpropertyofthecurrentdevelopertoequalthetotalnumberofdevelopersinDeveloperCollection,plusone.Later,weaddedthedevelopertothecollectionandsetthevalueofthesuccessMessageproperty.Rightafterthis,wesetthepropertysubmittedtoequaltotrue,whichwillresultinhidingtheform.

Page 311: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 312: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ListingallthestoreddevelopersNowthatwecanaddanewentrytothedevelopers’collection,let’sshowalistofallthedevelopersonthefrontpageofthe“Codersrepository”.

Openthefilech6/ts/step-1/home.tsandenterthefollowingcontent:

import{Component}from'angular2/core';

import{DeveloperCollection}from'./developer_collection';

@Component({

selector:'home',

templateUrl:'./home.html'

})

exportclassHome{

constructor(privatedevelopers:DeveloperCollection){}

getDevelopers(){

returnthis.developers.getAll();

}

}

Thereisnothingnewtoushere.WeextendthefunctionalityoftheHomecomponentbyprovidinganexternaltemplateandimplementingthegetDevelopersmethod,whichdelegatesitscalltotheinstanceofDeveloperCollectionthatisinjectedintheconstructor.

Thetemplateitselfissomethingthatwe’realreadyfamiliarwithaswell:

<tableclass="table"*ngIf="getDevelopers().length>0">

<thead>

<th>Email</th>

<th>Realname</th>

<th>Technology</th>

<th>Popular</th>

</thead>

<tr*ngFor="#devofgetDevelopers()">

<td>{{dev.email}}</td>

<td>{{dev.realName}}</td>

<td>{{dev.technology}}</td>

<td[ngSwitch]="dev.popular">

<span*ngSwitchWhen="true">Yes</span>

<span*ngSwitchWhen="false">Notyet</span>

</td>

</tr>

</table>

<div*ngIf="getDevelopers().length==0">

Therearenoanydevelopersyet

</div>

WelistallthedevelopersasrowswithinanHTMLtable.Foreachdeveloper,wecheckthestatusofitspopularflag.Ifitsvalueistrue,thenforthePopularcolumn,weshowaspanwiththetextYes,otherwisewesetthetexttoNo.

WhenyouenterafewdevelopersintheAddDeveloperpageandyounavigatetothe

Page 313: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

homepageafterthat,youshouldseearesultsimilartothefollowingscreenshot:

Fig.7

NoteYoucanfindthecompletefunctionalityoftheapplicationatch6/ts/multi-page-template-driven.

Page 314: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 315: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SummarySofar,wehaveexplainedthebasicsofroutinginAngular2.Wetookalookathowwecandefinedifferentroutesandimplementthecomponentsassociatedwiththemthataredisplayedonroutechange.Inordertolinktothedifferentroutes,weexplainedrouterLink,andwealsousedtherouter-outletdirectivesforpointingoutwherethecomponentsassociatedwiththeindividualroutesshouldberendered.

AnotherthingwetookalookatwastheAngular2formsfunctionalitywithbuilt-inandcustomvalidation.Afterthis,weexplainedtheNgModeldirective,whichprovidestoustwo-waydata-binding.

Inthenextchapter,wewillcoverhowwecandevelopmodel-drivenformsandchildandparametrizedroutes,usetheHttpmoduleformakingRESTfulcalls,andtransformdatawithcustompipes.

Page 316: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 317: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Chapter7.ExplainingPipesandCommunicatingwithRESTfulServicesInthelastchapter,wecoveredsomeverypowerfulfeaturesoftheframework.However,wecangoevendeeperintothefunctionalityofAngular’sformsmoduleandrouter.Inthenextsections,we’llexplainhowwecan:

Developmodel-drivenforms.Defineparameterizedroutes.Definechildroutes.UsetheHttpmoduleforcommunicationwithRESTfulAPIs.Transformdatawithcustompipes.

Wewillexplorealltheseconceptsintheprocessofextendingthefunctionalityofthe“Codersrepository”application.Atthebeginningofthepreviouschapter,wementionedthatwe’regoingtoallowimportofdevelopersfromGitHub.Butbeforeweimplementthisfeature,let’sextendthefunctionalityoftheform.

Page 318: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Developingmodel-drivenformsinAngular2Thesearegoingtobethelaststepsinfinishingthe“Codersrepository”.Youcanbuildontopofthecodeatch6/ts/step-1/(orch6/ts/step-2dependingonyourpreviouswork)inordertoextendtheapplication’sfunctionalitywiththenewconceptswe’regoingtocover.Thecompleteexampleislocatedatch7/ts/multi-page-model-driven.

Thisistheresultthatwearegoingtoachievebytheendofthissection:

Intheprecedingscreenshot,therearethefollowingtwoforms:

AformforimportingexistingusersfromGitHubthatcontains:

TheinputfortheGitHubhandle.AcheckboxthatpointsoutwhetherwewanttoimportthedeveloperfromGitHuborenteritmanually.

Aformforenteringnewusersmanually.

Thesecondformlooksexactlythewaywefinisheditinthelastsection.However,this

Page 319: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

time,itsdefinitionlooksalittlebitdifferent:

<formclass="formcol-md-4"

[ngFormModel]="addDevForm"[hidden]="submitted">

<!--TODO-->

</form>

Noticethatthistime,wedon’thavethesubmithandlerorthe#f="ngForm"attribute.Instead,weusethe[ngFormModel]attributeinordertobindtoapropertydefinedinsidethecomponent’scontroller.Byusingthisattribute,wecanbindtosomethingcalledControlGroup.Asitsnamestates,theControlGroupclassconsistsofalistofcontrolsgroupedtogetherwiththesetsofvalidationrulesassociatedwiththem.

Weneedtouseasimilardeclarationtoimportadeveloperform.However,thistime,wewillprovideadifferentvalueofthe[ngFormModel]attribute,sincewearegoingtodefineadifferentcontrolgroupinthecomponent’scontroller.Placethefollowingsnippetabovetheformweintroducedearlier:

<formclass="formcol-md-4"

[ngFormModel]="importDevForm"[hidden]="submitted">

<!--TODO-->

</form>

Now,let’sdeclaretheimportDevFormandaddDevFormpropertiesinthecomponent’scontroller:

import{ControlGroup}from'angular2/common';

@Component(…)

exportclassAddDeveloper{

importDevForm:ControlGroup;

addDevForm:ControlGroup;

constructor(privatedevelopers:DeveloperCollection,

fb:FormBuilder){…}

addDeveloper(){…}

}

Initially,weimportedtheControlGroupclassfromtheangular2moduleand,later,declaredtherequiredpropertiesinthecontroller.Let’salsonoticethatwehaveoneadditionalparameteroftheconstructorofAddDevelopercalledfbofthetypeFormBuilder.

FormBuilderprovidesaprogrammableAPIforthedefinitionofControlGroupswherewecanattachvalidationbehaviortoeachcontrolinthegroup.Let’susetheFormBulderinstancefortheinitializationoftheimportDevFormandaddDevFormproperties:

constructor(privatedevelopers:DeveloperCollection,

fb:FormBuilder){

this.importDevForm=fb.group({

githubHandle:['',Validators.required],

fetchFromGitHub:[false]

});

this.addDevForm=fb.group({

Page 320: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

realName:['',Validators.required],

email:['',validateEmail],

technology:['',Validators.required],

popular:[false]

});

}

TheFormBuilderinstancehasamethodcalledgroupthatallowsustodefineproperties,suchasthedefaultvaluesandthevalidatorsfortheindividualcontrolsinagivenform.

Accordingtotheprecedingsnippet,importDevFormhastwofieldsthatweintroducedearlier:githubHandleandfetchFromGitHub.WedeclaredthatthevalueofthegithubHandlecontrolisrequiredandsetthedefaultvalueofthecontrolfetchFromGitHubtofalse.

Inthesecondform,addDevForm,wedeclarefourcontrols.FortherealNamecontrolasthedefaultvalue,wesettheemptystringanduseValidators.requredinordertointroducevalidationbehavior(whichisexactlywhatwedidforthegithubHandlecontrol).Asavalidatorforthee-mailinput,wewillusethevalidateEmailfunctionandsetitsinitialvaluetoanemptystring.ThevalidateEmailfunctionusedforvalidationistheonewedefinedinthepreviouschapter:

functionvalidateEmail(emailControl){

if(!emailControl.value||

/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-

9-.]+$/.test(emailControl.value)){

returnnull;

}else{

return{'invalidEmail':true};

}

}

Thelasttwocontrolswedefineherearethetechnologycontrol,whichvalueisrequiredandhasanemptystringasitsinitialvalue,andthepopularcontrolwithitsinitialvaluesettofalse.

Page 321: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingcompositionofcontrolvalidatorsWetookalookathowwecanapplyasinglevalidatortoformcontrols.However,insomeapplications,thedomainmayrequiremorecomplexvalidationlogic.Forexample,ifwewanttoapplyboththerequiredandthevalidateEmailvalidatorstothee-mailcontrol,weshoulddothefollowing:

this.addDevForm=fb.group({

email:['',Validators.compose([

Validators.required,

validateEmail]

)],

});

ThecomposemethodoftheValidatorsobjectacceptsasanargumentanarrayofvalidatorsandreturnsanewvalidator.Thenewvalidator’sbehaviorisgoingtobeacompositionofthelogicdefinedintheindividualvalidatorspassedasanargument,andtheyaregoingtobeappliedinthesameorderastheywereintroducedinthearray.

ThepropertynamesintheobjectliteralpassedtothegroupmethodshouldmatchwiththevaluesthatwesettothengControlattributesoftheinputsinthetemplate.

ThisisthecompletetemplateofimportDevForm:

<formclass="formcol-md-4"

[ngFormModel]="importDevForm"[hidden]="submitted">

<divclass="form-group">

<labelclass="control-label"

for="githubHandleInput">GitHubhandle</label>

<div>

<inputid="githubHandleInput"

class="form-control"type="text"

[disabled]="!fetchFromGitHub"

ngControl="githubHandle">

<control-errorscontrol="githubHandle"

[errors]="{

'required':'TheGitHubhandleisrequired'

}"></control-errors>

</div>

</div>

<divclass="form-group">

<labelclass="control-label"

for="fetchFromGitHubCheckbox">

FetchfromGitHub

</label>

<inputclass="checkbox-inline"id="fetchFromGitHubCheckbox"

type="checkbox"ngControl="fetchFromGitHub"

[(ngModel)]="fetchFromGitHub">

</div>

</form>

Intheprecedingtemplate,youcannoticethatoncetheflagsubmittedhasthevaluetrue,

Page 322: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

sotheformwillbehiddenfromtheuser.Nexttothefirstinputelement,wesetthevalueofthengControlattributetogithubHandle.

NoteNotethatthevalueofthengControlattributeofthegiveninputelementmustmatchthenameweusedforitscorrespondingcontroldeclarationinthedefinitionofControlGroupwithinthecomponent’scontroller.

WithregardtothegithubHandlecontrol,wealsosetthedisabledattributetoequaltheresultoftheevaluationoftheexpression:!fetchFromGitHub.Thisway,whenthefetchFromGitHubcheckboxisunchecked,thegithubHandlecontrolwillbedisabled.Similarly,incaseoftheexampleintheprevioussections,weusedtheControlErrorscomponentwedefinedpreviously.Thistime,wesetasingleerrorwiththemessageTheGitHubhandleisrequired.

ThemarkupfortheformaddDevFormlooksquitesimilar,sowewon’tdescribeitindetailhere.Ifyou’renotcompletelysureofhowtoapproachdevelopingit,youcantakealookatthecompleteimplementationatch7/ts/multi-page-model-driven/add_developer.html.

Thelastpartofthetemplatewe’regoingtotakealookatistheSubmitbutton:

<buttonclass="btnbtn-default"

(click)="addDeveloper()"

[disabled]="(fetchFromGitHub&&!importDevForm.valid)||

(!fetchFromGitHub&&!addDevForm.valid)">

Add

</button>

ClickingonthebuttonwillinvoketheaddDevelopermethoddefinedinthecomponent’scontroller.Intheexpressionsetasvalueofthe[disabled]attribute,weinitiallycheckwhichformisselectedbyusingthevalueofthepropertyboundtothecheckbox,thatis,weverifywhethertheuserwantstoaddanewdeveloperorimportanexistingonefromGitHub.Ifthefirstoptionisselected(thatis,ifthecheckboxisnotchecked),weverifywhethertheControlGroupforaddinganewdeveloperisvalid.Ifitisvalid,thenthebuttonwillbeenabled,otherwiseitwillbedisabled.WewilldothesameincaseswhentheuserhascheckedthecheckboxforimportingadeveloperfromGitHub.

Page 323: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 324: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

ExploringtheHTTPmoduleofAngularNow,afterwedeveloptheformsforbothimportingexistingandaddingnewdevelopers,itisthetimetoimplementthelogicbehinditinthecontrollerofthecomponent.

Forthispurpose,weneedtocommunicatewiththeGitHubAPI.Althoughwecandothisdirectlyfromthecomponent’scontroller,bydoingitthisway,wecancoupleitwiththeRESTfulAPIofGitHub.Inordertoenforcefurtherseparationofconcerns,wecanextractthelogicforcommunicationwithGitHubintoaseparateservicecalledGitHubGateway.Openafilecalledgithub_gateway.tsandenterthefollowingcontent:

import{Injectable}from'angular2/core';

import{Http}from'angular2/http';

@Injectable()

exportclassGitHubGateway{

constructor(privatehttp:Http){}

getUser(username:string){

returnthis.http

.get(`https://api.github.com/users/${username}`);

}

}

Initially,weimportedtheHttpclassfromtheangular2/httpmodule.AlltheHTTP-relatedfunctionalityisexternalizedandisoutsidetheAngular’score.SinceGitHubGatewayacceptsadependency,whichneedstobeinjectedthroughtheDImechanismoftheframework,wewilldecorateitwiththe@Injectabledecorator.

TheonlyfunctionalityfromtheGitHub’sAPIwe’regoingtouseistheoneforfetchingusers,sowewilldefineasinglemethodcalledgetUser.Asanargument,itacceptstheGitHubhandleofthedeveloper.

NoteNotethatifyoumakemorethan60requestsperdaytotheGitHub’sAPI,youmightgettheerrorGitHubAPIRatelimitexceeded.ThisisduetotheratelimitsforrequestswithoutaGitHubAPItoken.Forfurtherinformation,visithttps://github.com/blog/1509-personal-api-tokens.

InsidethegetUsermethod,weusetheinstanceoftheHttpservicethatwe’vereceivedintheconstructorfunction.TheHttpservice’sAPIstaysasclosetotheHTML5fetchAPIaspossible.However,thereareacoupleofdifferences.Themostsignificantoneofthemisthatatthemomentofwritingthiscontent,allthemethodsoftheHttpinstancesreturnObservablesinsteadofPromises.

TheHttpserviceinstanceshavethefollowingAPI:

request(url:string|Request,options:RequestOptionsArgs):MakesarequesttothespecifiedURL.TherequestcanbeconfiguredusingRequestOptionsArgs:

Page 325: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

http.request('http://example.com/',{

method:'get',

search:'foo=bar',

headers:newHeaders({

'X-Custom-Header':'Hello'

})

});

get(url:string,options?:RequestOptionsArgs):MakesagetrequesttothespecifiedURL.Therequestheadersandotheroptionscanbeconfiguredusingthesecondargument.post(url:string,options?:RequestOptionsArgs):MakesapostrequesttothespecifiedURL.Therequestbody,headers,andotheroptionscanbeconfiguredusingthesecondargument.put(url:string,options?:RequestOptionsArgs):MakesaputrequesttothespecifiedURL.Therequestheadersandotheroptionscanbeconfiguredusingthesecondargument.patch(url:string,options?:RequestOptionsArgs):MakesapatchrequesttothespecifiedURL.Therequestheadersandotheroptionscanbeconfiguredusingthesecondargument.delete(url:string,options?:RequestOptionsArgs):MakesadeleterequesttothespecifiedURL.Therequestheadersandotheroptionscanbeconfiguredusingthesecondargument.head(url:string,options?:RequestOptionsArgs):MakesaheadrequesttothespecifiedURL.Therequestheadersandotheroptionscanbeconfiguredusingthesecondargument.

Page 326: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingAngular’sHTTPmoduleNow,let’simplementthelogicforimportingexistingusersfromGitHub!Openthefilech6/ts/step-2/add_developer.tsandenterthefollowingimports:

import{Response,HTTP_PROVIDERS}from'angular2/http';

import{GitHubGateway}from'./github_gateway';

AddHTTP_PROVIDERSandGitHubGatewaytothelistofprovidersoftheAddDevelopercomponent:

@Component({

providers:[GitHubGateway,FORM_PROVIDERS,HTTP_PROVIDERS]

})

classAddDeveloper{…}

Asthenextstep,wehavetoincludethefollowingparametersintheconstructoroftheclass:

constructor(privategithubAPI:GitHubGateway,

privatedevelopers:DeveloperCollection,

fb:FormBuilder){

//…

}

Thisway,theAddDeveloperclass’instanceswillhaveaprivatepropertycalledgithubAPI.

TheonlythingleftistoimplementtheaddDevelopermethodandallowtheusertoimportexistingdevelopersbyusingtheGitHubGatewayinstance.

OncetheuserpressestheAddbutton,weneedtocheckwhetherweneedtoimportanexistingGitHubuseroraddanewdeveloper.Forthispurpose,wecanusethevalueofthefetchFromGitHubcontrol:

if(this.importDevForm.controls['fetchFromGitHub'].value){

//Importdeveloper

}else{

//Addnewdeveloper

}

Ifithasatruthyvalue,thenwecaninvokethegetUsermethodofthegithubAPIpropertyandpassthevalueofthegithubHandlecontrolasanargument:

this.githubAPI.getUser(model.githubHandle)

InthegetUsermethod,wedelegatethecalltotheHttpservice’sgetmethod,whichreturnsanobservable.Inordertogettheresultthattheobservableisgoingtopush,weneedtopassacallbacktoitssubscribemethod:

this.githubAPI.getUser(model.githubHandle)

.map((r:Response)=>r.json())

.subscribe((res:any)=>{

//"res"containstheresponseoftheGitHub'sAPI

Page 327: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

});

Intheprecedingsnippet,wefirstestablishtheHTTPgetrequest.Afterthis,we’llgettheobservablethat,ingeneralcases,willemitaseriesofvalues(inthiscase,onlyasingleone—theresponseoftherequest)andmapthemtotheJSONrepresentationoftheirbodies.IftheresponsefailsoritsbodyisnotavalidJSONstring,thenwewillgetanerror.

NoteNotethatinordertoreducethesizeofRxJS,Angular’scoreteamhasincludedonlyitscore.Inordertousethemethodsmapandcatch,youneedtoaddthefollowingimportsatadd_developer.ts:

import'rxjs/add/operator/map';

import'rxjs/add/operator/catch';

Nowlet’simplementthebodyofthesubscribecallback:

letdev=newDeveloper();

dev.githubHandle=res.login;

dev.email=res.email;

dev.popular=res.followers>=1000;

dev.realName=res.name;

dev.id=res.id;

dev.avatarUrl=res.avatar_url;

this.developers.addDeveloper(dev);

this.successMessage=`Developer${dev.githubHandle}successfullyimported

fromGitHub`;

Intheprecedingexample,wesetthepropertiesofanewDeveloperinstance.Here,weestablishedthemappingbetweentheobjectreturnedfromGitHub’sAPIandthedeveloper’srepresentationinourapplication.Wealsoconsideredadeveloperaspopularifsheorhehasabove1,000followers.

TheentireimplementationoftheaddDevelopermethodcanbefoundatch7/ts/multi-page-model-driven/add_developer.ts.

NoteInordertohandlefailedrequests,wecanusethecatchmethodoftheobservableinstances:

this.githubAPI.getUser(model.githubHandle)

.catch((error,source,caught)=>{

console.log(error)

returnerror;

})

Page 328: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 329: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningparameterizedviewsAsthenextstep,let’sdedicateaspecialpageforeachdeveloper.Insideofit,we’llbeabletotakeadetailedlookathisorherprofile.Oncetheuserclicksonthenameofanyofthedevelopersonthehomepageoftheapplication,heorsheshouldberedirectedtoapagewithadetailedprofileoftheselecteddeveloper.Theendresultwilllookasfollows:

Inordertodothis,weneedtopassanidentifierofthedevelopertothecomponentthatshowsdeveloper’sdetailedprofile.Openapp.tsandaddthefollowingimport:

import{DeveloperDetails}from'./developer_details';

Wehaven’tdevelopedtheDeveloperDetailscomponentyet,soifyouruntheapplication,youwillgetanerror.Wewilldefinethecomponentinthenextparagraph,butbeforethis,let’salterthe@RouteConfigdefinitionoftheAppcomponent:

@RouteConfig([

//…

newRoute({

component:DeveloperDetails,

name:'DeveloperDetails',

path:'/dev-details/:id/...'

}),

//…

])

classApp{}

WeaddedasingleroutewiththeDeveloperDetailscomponentassociatedwithit,andasanalias,weusedthestring"DeveloperDetails".

Page 330: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Thevalueofthecomponentpropertyisareferencetotheconstructorofthecomponent,whichshouldhandlethegivenroute.Oncethesourcecodeoftheapplicationgetsminifiedforproduction,thecomponentnamemaydifferfromtheonewe’veentered.ThiswillcreateproblemswhenreferencingtheroutewithinthetemplatesusingtherouterLinkdirective.Inordertopreventthisfromhappening,thecoreteamintroducedthenamepropertythat,inthiscase,equalstothenameofthecontroller.

NoteAlthoughinalltheexamplessofar,wesetthealiasoftheroutetobethesameasthenameofthecomponent’scontroller,thisisnotrequired.Thisconventionisusedforsimplicity,sinceitcouldbeconfusingtointroducetwonames:oneforpointingtotherouteandanotheroneforthecontrollerassociatedwiththegivenroute.

Inthepathproperty,wedeclarethattheroutehasasingleparametercalledid,andwith"...",wehinttheframeworkthatthisroutewillhavenestedroutesinsideofit.

Now,let’spasstheidofthecurrentdeveloperasaparametertotherouterLinkdirective.Openhome.htmlinyourworkingdirectoryandreplacethetablecellwherewedisplaythedeveloper’srealNamepropertywiththefollowingcontent:

<td>

<a[routerLink]="['/DeveloperDetails',

{'id':dev.id},'DeveloperBasicInfo']">

{{dev.realName}}

</a>

</td>

ThevalueoftherouterLinkdirectiveisanarraywiththefollowingthreeelements:

'/DeveloperDetails':Astringthatshowstherootroute{'id':dev.id}:Anobjectliteralthatdeclarestherouteparameters'DeveloperBasicInfo':ThenameofaroutethatshowswhichcomponentwithinthenestedrouteinthecomponentwiththealiasDeveloperDetailsshouldberendered

Page 331: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 332: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DefiningnestedroutesNowlet’sjumptotheDeveloperDetailsdefinition.Inyourworkingdirectory,createafilecalleddeveloper_details.tsandenterthefollowingcontent:

import{Component}from'angular2/core';

import{

ROUTER_DIRECTIVES,

RouteConfig,

RouteParams

}from'angular2/router';

import{Developer}from'./developer';

import{DeveloperCollection}from'./developer_collection';

@Component({

selector:'dev-details',

template:`…`,

})

@RouteConfig(…)

exportclassDeveloperDetails{

publicdev:Developer;

constructor(routeParams:RouteParams,

developers:DeveloperCollection){

this.dev=developers.getUserById(

parseInt(routeParams.params['id'])

);

}

}

Intheprecedingsnippet,wedefinedacomponentwithcontrollercalledDeveloperDetails.Youcannoticethatwithinthecontroller’sconstructor,throughtheDImechanismofAngular2,weinjectedaparameterassociatedwiththeRouteParamstoken.Theinjectedparameterprovidesusaccesstotheparametersvisiblebythecurrentroute.Wecanaccessthemusingtheparamspropertyoftheinjectedobjectandaccessthetargetparameterusingitsnameasakey.

SincetheparameterwegotfromrouteParams.params['id']isastring,weneedtoparseittoanumberinordertogetthedeveloperassociatedwiththegivenroute.Nowlet’sdefinetheroutesassociatedwithDeveloperDetails:

@Component(…)

@RouteConfig([{

component:DeveloperBasicInfo,

name:'DeveloperBasicInfo',

path:'/'

},

{

component:DeveloperAdvancedInfo,

name:'DeveloperAdvancedInfo',

path:'/dev-details-advanced'

}])

exportclassDeveloperDetails{…}

Page 333: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Intheprecedingsnippet,thereisnothingnewforus.Theroutedefinitionfollowstheexactsameruleswe’realreadyfamiliarwith.

Now,tothetemplateofthecomponent,let’saddlinksassociatedwiththeindividualnestedroutes:

@Component({

selector:'dev-details',

directives:[ROUTER_DIRECTIVES],

template:`

<sectionclass="col-md-4">

<ulclass="navnav-tabs">

<li>

<a[routerLink]="['./DeveloperBasicInfo']">

Basicprofile

</a>

</li>

<li>

<a[routerLink]="['./DeveloperAdvancedInfo']">

Advanceddetails

</a>

</li>

</ul>

<router-outlet/>

</section>

`,

})

@RouteConfig(…)

exportclassDeveloperDetails{…}

Withinthetemplate,wedeclaretworelativetothecurrentpathlinks.ThefirstonepointstoDeveloperBaiscInfo,whichisthenameofthefirstroutedefinedwithin@RouteConfigoftheDeveloperDetailscomponent,andrespectively,thesecondonepointstoDeveloperAdvancedInfo.

Sincetheimplementationsofboththecomponentsarequitesimilar,let’stakealookonlyatDeveloperBasicInfo.Asanexercise,youcandevelopthesecondoneortakealookatitsimplementationatch7/ts/multi-page-model-driven/developer_advanced_info.ts:

import{

Component,

Inject,

forwardRef,

Host

}from'angular2/core';

import{DeveloperDetails}from'./developer_details';

import{Developer}from'./developer';

@Component({

selector:'dev-details-basic',

styles:[…],

template:`

<h2>{{dev.realName}}</h2>

<img*ngIf="dev.avatarUrl==null"

class="avatar"src="./gravatar-60-grey.jpg"width="150">

Page 334: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

<img*ngIf="dev.avatarUrl!=null"

class="avatar"[src]="dev.avatarUrl"width="150">

`

})

exportclassDeveloperBasicInfo{

dev:Developer;

constructor(@Inject(forwardRef(()=>DeveloperDetails))

@Host()parent:DeveloperDetails){

this.dev=parent.dev;

}

}

Intheprecedingsnippet,weinjectedtheparentcomponentcombiningthe@[email protected]@Inject,weuseforwardRef,sincewehaveacirculardependencybetweenthepackagesdeveloper_basic_infoanddeveloper_details(insidedeveloper_basic_info,weimportdeveloper_details,andwithindeveloper_details,weimportdeveloper_basic_info).

Weneedareferencetotheinstanceoftheparentcomponentinordertogettheinstanceofthecurrentdevelopercorrespondingtotheselectedroute.

Page 335: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 336: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TransformingdatawithpipesItistimeforthelastbuildingblockthatAngular2providesforthedevelopmentofapplicationsthatwehaven’tcoveredindetailyet—thepipes.

JustlikethefiltersinAngularJS1.x,pipesareintendedtoencapsulateallthedata-transformationlogic.Let’stakealookatthetemplateofthehomepageoftheapplicationwejustdeveloped:

<td[ngSwitch]="dev.popular">

<span*ngSwitch-when="true">Yes</span>

<span*ngSwitch-when="false">Notyet</span>

</td>

Intheprecedingsnippet,dependingonthevalueofthepopularproperty,weshoweddifferentdatausingtheNgSwitchandNgSwitchThendirectives.Althoughthisworks,itisredundant.

Page 337: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DevelopingstatelesspipesLet’sdevelopapipethattransformsthevalueofthepopularpropertyandusesitintheplaceofNgSwitchandNgSwitchThen.Thepipewillacceptthreearguments:avaluethatshouldbetransformed,astringthatshouldbedisplayedwhenthevalueistruthy,andanotherstringthatshouldbedisplayedincaseofafalsyvalue.

WiththeuseofanAngular2custompipe,wewillbeabletosimplifythetemplateto:

<td>{{dev.popular|boolean:'Yes':'No'}}</td>

Wecouldevenuseemojis:

<td>{{dev.popular|boolean:'':''}}</td>

WeapplythepipetothevaluethesamewaywedoinAngularJS1.x.Theargumentswepasstothepipeshouldbeseparatedbythecolon(:)symbol.

InordertodevelopanAngular2pipe,weneedthefollowingimports:

import{Pipe,PipeTransform}from'angular2/core';

ThePipedecoratorcanbeusedforaddingmetadatatotheclassthatimplementsthedatatransformationlogic.ThePipeTransformisaninterfacewithasinglemethodcalledtransform:

import{Pipe,PipeTransform}from'angular2/core';

@Pipe({

name:'boolean'

})

exportclassBooleanPipeimplementsPipeTransform{

constructor(){}

transform(flag:boolean,args:string[]):string{

returnflag?args[0]:args[1];

}

}

TheprecedingsnippetistheentireimplementationofBooleanPipe.Thenameofthepipedeterminesthewayitshouldbeusedintemplates.

ThelastthingweneedtodobeforebeingabletousethepipeistoaddtheBooleanPipeclasstothelistofpipesusedbytheHomecomponent(BooleanPipealreadyholdsthemetadataattachedtoitbythe@Pipedecorator,soitsnameisattachedtoit):

@Component({

pipes:[BooleanPipe],

})

exportclassHome{

constructor(privatedevelopers:DeveloperCollection){}

getDevelopers(){…}

}

Page 338: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingAngular’sbuilt-inpipesAngular2providesthefollowingsetofbuilt-inpipes:

CurrencyPipe:Thispipeisusedforformattingcurrencydata.Asanargument,itacceptstheabbreviationofthecurrencytype(thatis,"EUR","USD",andsoon).Itcanbeusedinthefollowingway:

{{currencyValue|currency:'USD'}}<!--USD42-->

DatePipe:Thispipeisusedforthetransformationofdates.Itcanbeusedinthefollowingway:

{{dateValue|date:'shortTime'}}<!--12:00AM-->

DecimalPipe:Thispipeisusedfortransformationofdecimalnumbers.Theargumentitacceptsisofthefollowingform:"{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}".Itcanbeusedinthefollowingway:

{{42.1618|number:'3.1-2'}}<!--042.16-->

JsonPipe:ThistransformsaJavaScriptobjectintoaJSONstring.Itcanbeusedinthefollowingway:

{{{foo:42}|json}}<!--{"foo":42}-->

LowerCasePipe:Thistransformsastringtolowercase.Itcanbeusedinthefollowingway:

{{FOO|lowercase}}<!--foo-->

UpperCasePipe:Thistransformsastringtouppercase.Itcanbeusedinthefollowingway:

{{'foo'|uppercase}}<!--FOO-->

PercentPipe:Thistransformsanumberintoapercentage.Itcanbeusedinthefollowingway:

{{42|percent:'2.1-2'}}<!--4,200.0%-->

SlicePipe:Thisreturnsasliceofanarray.Thepipeacceptsthestartandtheendindexesoftheslice.Itcanbeusedinthefollowingway:

{{[1,2,3]|slice:1:2}}<!--2-->

AsyncPipe:Thisisastatefulpipethatacceptsanobservableorapromise.We’regoingtotakealookatitattheendofthechapter.

Page 339: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

DevelopingstatefulpipesTherewasonecommonthingbetweenallthepipesmentionedearlier—allofthemreturnexactlythesameresulteachtimeweapplythemtothesamevalueandpassthemthesamesetofarguments.Suchpipesthatholdthereferentiallytransparencypropertyarecalledpurepipes.

The@Pipedecoratoracceptsanobjectliteralofthefollowingtype:{name:string,pure?:boolean},wherethedefaultvalueforthepurepropertyistrue.Thismeansthatwhenwedecorateagivenclassusingthe@Pipedecorator,wecandeclarewhetherwewantthepipeitimplementsthelogicfortobeeitherstatefulorstateless.Thepurepropertyisimportant,becauseincasethepipeisstateless(thatis,itreturnsthesameresultincaseitisappliedoverthesamevaluewiththesamesetofarguments),thechangedetectioncanbeoptimized.

Nowlet’sbuildastatefulpipe!OurpipewillmakeanHTTPgetrequesttoaJSONAPI.Forthispurpose,wewillusetheangular2/httpmodule.

NoteNotethathavingbusinesslogicinapipeisnotconsideredasabestpractice.Thistypeoflogicshouldbeextractedintoaservice.Theexamplehereisforlearningpurposesonly.

Inthiscase,thepipeneedstoholdadifferentstatedependingonthestatusoftherequest(thatis,whetheritispendingorcompleted).Wewillusethepipeinthefollowingway:

{{"http://example.com/user.json"|fetchJson|json}}

Thisway,weapplythefetchJsonpipeovertheURL,andoncewehaveresponsefromtheremoteserviceandthepromisefortherequesthasbeenresolved,wecanapplythejsonpipeovertheobjectwegotfromtheresponse.TheexamplealsoshowshowwecanchainpipeswithAngular2.

Similarly,incaseofthepreviousexample,forthedevelopmentofastatelesspipe,wehavetoimportPipeandPipeTransform.However,thistime,becauseoftheHTTPrequestfunctionality,wealsoneedtoimporttheHttpandResponseclassesfromthe'angular2/http'module:

import{Pipe,PipeTransform}from'angular2/core';

import{Http,Response}from'angular2/http';

import'rxjs/add/operator/toPromise';

EachtimeithappenstoapplythefetchJsonpipetoadifferentargumentcomparedtotheonewegotinthepreviousinvocation,weneedtomakeanewHTTPgetrequest.Thismeansthatasthestateofthepipe,weneedtokeepatleastthevaluesoftheresponseoftheremoteserviceandthelastURL:

@Pipe({

name:'fetchJson',

pure:false

})

exportclassFetchJsonPipeimplementsPipeTransform{

Page 340: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

privatedata:any;

privateprevUrl:string;

constructor(privatehttp:Http){}

transform(url:string):any{…}

}

Theonlypieceoflogicleftisthetransformmethod:

transform(url:string):any{

if(this.prevUrl!==url){

this.http.get(url).toPromise(Promise)

.then((data:Response)=>data.json())

.then(result=>this.data=result);

this.prevUrl=url;

}

returnthis.data||{};

}

Insideofit,weinitiallycomparedtheURLpassedasanargumentwiththeonewecurrentlykeepareferenceto.Iftheyaredifferent,weinitiateanewHTTPgetrequestusingthelocalinstanceoftheHttpclass,whichwaspassedtotheconstructorfunction.Oncetherequestiscompleted,weparsetheresponsetoJSONandsetthedatapropertytotheresult.

Now,let’ssupposethepipehasstartedanHttpgetrequest,andbeforeitiscompleted,thechangedetectionmechanisminvokesthepipeagain.Inthiscase,wewillcomparetheprevUrlpropertywiththeurlparameter.Incasetheyarethesame,wewon’tperformanewhttprequest,andwewillimmediatelyreturnthevalueofthedataproperty.IncaseprevUrlhasadifferentvaluefromurl,wewillstartanewrequest.

Page 341: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingstatefulpipesNowlet’susethepipethatwedeveloped!Theapplicationthatwearegoingtoimplementprovidestotheuseratextinputandabutton.Oncetheuserentersavalueinthetextinputandpressesthebutton,belowthetextinputwillappeartheavatarcorrespondingtotheGitHubuser,asshowninthefollowingscreenshot:

Now,let’sdevelopasamplecomponent,whichwillallowustoentertheGitHubuser’shandle:

//ch7/ts/statful_pipe/app.ts

@Component({

selector:'app',

providers:[HTTP_PROVIDERS],

pipes:[FetchJsonPipe,ObjectGetPipe],

template:`

<inputtype="text"#input>

<button(click)="setUsername(input.value)">GetAvatar</button>

`

})

classApp{

username:string;

setUsername(user:string){

this.username=user;

}

}

Intheprecedingexample,weaddedFetchJsonPipeusedbytheAppcomponent.TheonlythingleftistoshowtheGitHubavataroftheuser.Wecaneasilyachievethisbyalteringthetemplateoftheprecedingcomponentwiththefollowingimgdeclaration:

<imgwidth="160"[src]="(('https://api.github.com/users/'+username)|

fetchJson).avatar_url">

Page 342: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Initially,weappendedtheGitHubhandletothebaseURLusedforfetchingusersfromtheAPI.Later,weappliedthefetchJsonfilteroverit,andfromthereturnedresult,wegottheavatar_urlproperty.

NoteAlthoughthepreviousexampleworks,itisunnaturaltohavebusinesslogicinyourpipes.ItwillbefarbettertoimplementthelogicforcommunicationwiththeGitHub’sAPIintoaserviceor,atleast,invokethegetmethodoftheinstanceoftheHttpclassinacomponent.

Page 343: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UsingAngular’sAsyncPipeAngular’sAsyncPipetransformmethodacceptsasanargumentanobservableorapromise.Oncetheargumentpushesavalue(thatis,thepromisehasbeenresolvedorthesubscribecallbackoftheobservableisinvokedwithavalue),AsyncPipewillreturnitasaresult.Let’stakealookatthefollowingexample:

//ch7/ts/async-pipe/app.ts

@Component({

selector:'greeting',

template:'Hello{{greetingPromise|async}}'

})

classGreeting{

greetingPromise=newPromise<string>(resolve=>this.resolve=resolve);

resolve:Function;

constructor(){

setTimeout(_=>{

this.resolve('Foobar!');

},3000);

}

}

Here,wedefinedanAngular2component,whichhastwoproperties:greetingPromiseofthetypePromise<string>andresolveofthetypeFunction.WeinitializedthegreetingPromisepropertywithanewPromise<string>instance,andasvalueoftheresolveproperty,wesettheresolvecallbackofthepromise.

Intheconstructoroftheclass,westartatimeoutwiththedurationof3,000ms,andinsideofitscallback,weresolvethepromise.Oncethepromiseisresolved,thevalueoftheexpression{{greetingPromise|async}}willbeevaluatedtothestringFoobar!.TheendresultthattheuserwillseeonthescreenisthetextHelloFoobar!.

TheasyncpipeisextremelypowerfulwhenwecombineitwithanHttprequestortogetherwithanobservable,whichpushesasequenceofvalues.

UsingAsyncPipewithobservablesWe’realreadyfamiliarwiththeconceptofobservablesfromthepreviouschapters.Wecansaythatanobservableobjectallowsustosubscribetotheemissionofasequenceofvalues,forinstance:

letobserver=newObservable<number>(observer=>{

setInterval(()=>{

observer.next(newDate().getTime());

},1000);

});

observer.subscribe(date=>console.log(date));

Oncewesubscribetotheobservable,itwillstartemittingvalueseachsecond,whicharegoingtobeprintedintheconsole.Let’scombinethissnippetwiththecomponent’sdefinitionandimplementasimpletimer:

//ch7/ts/async-pipe/app.ts

Page 344: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

@Component({

selector:'timer'

})

classTimer{

username:string;

timer:Observable<number>;

constructor(){

letcounter=0;

this.timer=newObservable<number>(observer=>{

setInterval(()=>{

observer.next(newDate().getTime());

},1000);

});

}

}

Theonlythingleftinordertobeabletousethetimercomponentistoadditstemplate.Wecansubscribetotheobservabledirectlyinourtemplatebyusingtheasyncpipe:

{{timer|async|date:"medium"}}

Thisway,eachsecondwewillgetthenewvalueemittedbytheobservable,andthedatepipewilltransformitintoareadableform.

Page 345: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 346: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SummaryInthischapter,wetookadeepdiveintotheAngular2formsbydevelopingamodel-drivenoneandcombiningitwiththehttpmoduleinordertobeabletoadddeveloperstoourrepository.Wetookalookatsomeadvancedfeaturesofthenewcomponent-basedrouterandsawhowwecanuseanddevelopourcustomizedstatefulandstatelesspipes.

ThenextchapterwillbededicatedtohowwecanmakeourAngular2applicationsSEO-friendlybytakingadvantageoftheserver-siderenderingthatthemoduleuniversalprovides.Wewillalsotakealookatangular-cliandtheothertoolsthatmakeourexperienceasdevelopersbetter.

Page 347: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 348: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Chapter8.DevelopmentExperienceandServer-SideRenderingWearealreadyfamiliarwithallthecoreconceptsofAngular2.Weknowhowtodevelopacomponent-baseduserinterface,takingadvantageofallthebuildingblocksthattheframeworkprovides—directives,components,dependencyinjections,pipes,forms,andthebrandnewcomponent-basedrouter.

Forthenextstep,we’lllookatwheretobeginwhenwewanttobuildasingle-pageapplication(SPA)fromscratch.Thischapterdescribeshowtodothefollowing:

UseWebWorkersforperformance-sensitiveapplications.BuildSEO-friendlyapplicationswithserver-siderendering.Bootstrapaprojectasquicklyaspossible.Enhanceourexperienceasdevelopers.

So,let’sbegin!

Page 349: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

RunningapplicationsinWebWorkersWhentalkingaboutperformanceinthecontextoffrontendwebdevelopment,wecaneithermeannetwork,computational,orrenderingperformance.Inthissection,we’llconcentrateonrenderingandcomputationalperformance.

First,let’smakeaparallelbetweenawebapplicationandavideo,andbetweenabrowserandavideoplayer.Thebiggestdifferencebetweenthewebapplicationrunninginthebrowserandthevideofileplayinginthevideoplayeristhatthewebpageneedstobegenerateddynamically,incontrasttothevideowhichhasbeenrecorded,encoded,anddistributed.However,inboththecases,theuseroftheapplicationseesasequenceofframes;thecoredifferenceishowtheseframesarebeinggenerated.Intheworldofvideoprocessing,whenweplayavideo,wehaveitalreadyrecorded;itistheresponsibilityofthevideodecodertoextracttheindividualframesbasedonthecompressionalgorithm.Incontrasttothis,ontheWeb,JavaScript,andCSSareinchargeofproducingframes,renderedbythebrowser’srenderingengine.

Inthecontextofthebrowser,wecanthinkofeachframeasasnapshotofthewebpageatagivenmoment.Thedifferentframesarerenderedfastoneafteranother,sointheory,theenduseroftheapplicationshouldseethemsmoothlyincorporatedtogether,justlikeavideoplayedinavideoplayer.

OntheWeb,wearetryingtoreach60fps(framespersecond),whichmeansthateachframehasabout16mstobecomputedandrenderedonthescreen.Thisdurationincludesthetimerequiredbythebrowsertomakeallthenecessarycalculationsforthelayoutandtherenderingofthepage,andalsothetimethatourJavaScriptneedstoexecute.

Intheend,wehavelessthan16ms(becauseofthebrowserrenderingfunctionalitythattakestimedependingonthecalculationsitneedstoperform)forourJavaScripttofinishexecution.Ifitdoesn’tfitinthisduration,theframeratewilldropbyhalf.SinceJavaScriptisasingle-threadedlanguage,allthecalculationsneedtohappeninthemainUIthreadthat,inthecaseofcomputationally-intensiveapplications(suchasimageorvideoprocessing,marshalingandunmarshalingbigJSONstrings,andsoon),canleadtoverypooruserexperiencebecauseoftheframesbeingdropped.

HTML5introducedanAPIcalledWebWorkers,whichallowstheexecutionofclient-sidecodeinthebrowserenvironmentintomultiplethreads.Forsimplicity,thestandarddoesn’tallowsharedmemorybetweenindividualthreads,butinsteadallowscommunicationwithmessagepassing.ThemessagesexchangedbetweenWebWorkersandthemainUIthreadmustbestrings,whichoftenrequirestheserializationanddeserializationofJSONstrings.

Thelackofsharedmemorybetweentheindividualworkers,andtheworkersandthemainUIthreadbringsacoupleoflimitations,suchas:

DisabledaccesstotheDOMbytheworkerthreads.Globalvariablescannotbesharedamongtheindividualcomputationalunits(thatis,workerthreadsandmainUIthreadsandviceversa).

Page 350: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WebWorkersandAngular2BecauseoftheplatformagnosticdesignofAngular2,thecoreteamdecidedtotakeadvantageofthisAPI,andduringthesummerof2015,GoogleembeddedWebWorkerssupportintotheframework.ThisfeatureallowsmostoftheAngular2applicationstoberunonaseparatethread,makingthemainUIthreadresponsibleonlyforrendering.Thishelpsusachievethegoalof60fpsmucheasilythanrunningtheentireapplicationinasinglethread.

TheWebWorkerssupportisnotenabledbydefault.Whenenablingit,weneedtokeepsomethinginmind—inaWebWorkers-readyapplication,thecomponentsarenotgoingtoberuninthemainUIthread,whichdoesnotallowustodirectlymanipulatetheDOM.Inthiscase,weneedtousebindings,suchasinputs,outputs,andacombinationofbothwithNgModel.

Page 351: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

BootstrappinganapplicationrunninginWebWorkerLet’smaketheto-doapplicationthatwedevelopedinChapter4,GettingStartedwithAngular2ComponentsandDirectivesworkinWebWorkers.Youcanfindtheexamplethatwe’llexploreatch8/ts/todo_webworkers/.

Firstofall,let’sdiscussthechangesthatweneedtomake.Takealookatch4/ts/inputs-outputs/app.ts.Noticethatinsideofapp.ts,weincludedthebootstrapfunctionfromtheangular2/platform/browsermodule.Thisisthefirstthingweneedtomodify!Thebootstrapprocessofanapplicationrunninginabackgroundprocessisdifferent.

Beforerefactoringourcode,let’stakealookatadiagramthatillustratesthebootstrapprocessofatypicalAngular2applicationrunninginWebWorkers:

JasonTeplitz,whoimplementedtheWebWorkersupportinAngular2,presentedthisdiagramduringhistalkonAngularConnect2015.

Thediagramhastwoparts:UIandWebWorker.UIshowstheactionsperformedduringinitializationinthemainUIthread;theWebWorkerpartofthediagramshowshowtheapplicationgetsbootstrappedinthebackgroundthread.Now,let’sexplainthebootstrapprocessstepbystep.

Page 352: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

First,theuseropenstheindex.htmlpage,whichtriggersthedownloadofthefollowingtwofiles:

TheUIbundleofAngular2usedforapplicationsrunninginWebWorker.Thesystem.jsbundle(wetalkedabouttheglobalobjectSysteminChapter3,TypeScriptCrashCourse.Wecanthinkofthesystem.jsbundleasapolyfillforthemoduleloader).

Usingsystem.js,wedownloadthescriptusedfortheinitializationofthepartoftheapplicationrunninginthemainUIthread.Thisscriptstartsloader.jsinWebWorker.Thisisthefirstscriptthatisrunninginabackgroundthread.Oncetheworkerisstarted,loader.jswilldownloadsystem.jsandthebundleofAngular2,whichismeanttoberuninthebackgroundthread.Thefirstrequestwillusuallyhitthecachebecausesystem.jsisalreadyrequestedbythemainthread.Usingthemoduleloader,wedownloadthescriptthatisresponsibleforbootstrappingthebackgroundappbackground_bootstrap.js,whichwillfinallystartthefunctionalityofourapplicationinthebackground.

Fromnowon,theentireapplicationthatwebuiltwillberuninWebWorkerandwillexchangemessageswiththemainUIthreadforrespondingtousereventsandrenderinginstructions.

Nowthatweareawareofthebasicflowofeventsduringinitializationwhenusingworkers,let’srefactorourto-doapplicationtotakeadvantageofthem.

Page 353: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

MigratinganapplicationtoWebWorkerInsideofindex.html,weneedtoaddthefollowingscripts:

<!--ch8/ts/todo_webworkers/index.html-->

<scriptsrc="/node_modules/systemjs/dist/system.src.js">

</script>

<scriptsrc="/node_modules/angular2/bundles/angular2-polyfills.js">

</script>

<scriptsrc="/node_modules/angular2/bundles/web_worker/ui.dev.js">

</script>

<script>

System.config({

baseURL:'/dist/dev/ch8/ts/todo_webworkers/'

});

System.import('./bootstrap.js')

.catch(function(){

console.log('Reportthiserrorto

https://github.com/mgechev/switching-to-angular2/issues',e);

});

</script>

Intheprecedingsnippet,we’veincludedreferencestosystem.js,angular2-polyfillsthatincludeszone.jsandtheothersusedbyAngularlibraries,andui.dev.jswhichisthebundlethatneedstoberuninthemainUIthread.

Rightafterthis,wewillconfiguresystem.jsbysettingthebaseURLpropertyofthemoduleloader.Forthenextstep,wewillexplicitlyimportthebootstrap.jsfile,whichcontainsthelogicusedforstartingtheloader.jsscriptinWebWorker.

Let’sexplorebootstrap.js,whichistheoriginalofthetranspiledbootstrap.js:

//ch8/ts/todo_webworkers/bootstrap.ts

import{platform,Provider}from'angular2/core';

import{

WORKER_RENDER_APPLICATION,

WORKER_RENDER_PLATFORM,

WORKER_SCRIPT

}from'angular2/platform/worker_render';

platform([WORKER_RENDER_PLATFORM])

.application([WORKER_RENDER_APPLICATION,

newProvider(WORKER_SCRIPT,{useValue:'loader.js'})]);

Inthisfile,wesettheplatformtothetypeWORKER_RENDER_PLATFORMandtheapplicationtypetoWORKER_RENDER_APPLICATION.WeconfiguredtheproviderusedforinjectingtheWORKER_SCRIPTtokentousethevalue'loader.js'.Aswesaid,loader.jsisgoingtoruninabackgroundthread.Thescriptislocatedintheapplication’sroot.

Now,wecanmovetotherightofthediagramgivenintheBootstrappinganapplicationrunninginaWebWorkersection.Thelogicinloader.jsisquitesimple:

Page 354: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

//ch8/ts/todo_webworkers/loader.ts

importScripts("/node_modules/systemjs/dist/system.src.js",

"/node_modules/angular2/bundles/web_worker/worker.dev.js",

"/node_modules/angular2/bundles/angular2-polyfills.js");

System.config({

baseURL:'/dist/dev/ch8/ts/todo_webworkers/',

});

System.import('./background_app.js')

.then(()=>console.log('Theapplicationhasstartedsuccessfully'),

error=>console.error('Errorloadingbackground',error));

Asthefirststep,weimportsystem.js,theWebWorkersbundleofAngular2(worker.dev.js),andalltherequiredpolyfills.Then,weconfigurethebackgroundinstanceofthemoduleloaderandimportthebackground_appfile,whichcontainsthelogicofourapplicationaswellastheWebWorkersbootstrapcall.

Now,let’sexplorehowwebootstraptheapplicationinsideWebWorker:

import{platform}from'angular2/core';

import{

WORKER_APP_PLATFORM,

WORKER_APP_APPLICATION

}from'angular2/platform/worker_app';

//Logicfortheapplication…

platform([WORKER_APP_PLATFORM])

.application([WORKER_APP_APPLICATION])

.bootstrap(TodoApp);

JustlikeinthebootstrapinthemainUIthread,wespecifythetypeoftheplatformandthetypeoftheapplicationthatwewanttobootstrap.Inthefinalstep,wesettherootcomponentjustlikewedidinthestandardbootstrapprocess.TheTodoAppcomponentisdefinedbetweentheimportsandtheinitializationcallsinthebackground_appfile.

Page 355: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

MakinganapplicationcompatiblewithWebWorkersAswesaid,thecodethatrunsinthecontextofWebWorkerdoesnothaveaccesstotheDOM.Let’sseewhatchangesweneedtomakeinordertoaddressthislimitation.

ThisistheoriginalimplementationoftheInputBoxcomponent:

//ch4/ts/inputs-outputs/app.ts

@Component({

selector:'input-box',

template:`

<input#todoInput[placeholder]="inputPlaceholder">

<button(click)="emitText(todoInput.value);

todoInput.value='';">

{{buttonLabel}}

</button>

`

})

classInputBox{

@Input()inputPlaceholder:string;

@Input()buttonLabel:string;

@Output()inputText=newEventEmitter<string>();

emitText(text:string){

this.inputText.emit(text);

}

}

Noticethatinsidethetemplate,wenamedtheinputelementtodoInputanduseditsreferencewithintheexpressionsetasthehandleroftheclickevent.ThiscodewillnotbeabletoruninWebWorker,sincewedirectlyaccessaDOMelementinsidethetemplate.Inordertotakecareofthis,weneedtorefactorthesnippet,soitusesAngular2bindingsinsteadofdirectlytouchinganyelements.WecaneitheruseinputswhenasingledirectionbindingmakessenseorNgModelforachievingtwo-waydata-binding,whichismorecomputationally-intensive.

Let’suseNgModel:

//ch8/ts/todo_webworkers/background_app.ts

import{NgModel}from'angular2/common';

@Component({

selector:'input-box',

template:`

<input[placeholder]="inputPlaceholder"[(ngModel)]="input">

<button(click)="emitText()">

{{buttonLabel}}

</button>

`

})

classInputBox{

@Input()inputPlaceholder:string;

@Input()buttonLabel:string;

@Output()inputText=newEventEmitter<string>();

Page 356: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

input:string;

emitText(){

this.inputText.emit(this.input);

this.input='';

}

}

InthisversionoftheInputBoxcomponent,wewillcreateatwo-waydata-bindingbetweentheinputelementandtheinputpropertyoftheInputBoxcomponent.Oncetheuserclicksonthebutton,theemitTextmethodwillbeinvoked,whichwilltriggeraneweventemittedbyinputTextEventEmitter.Inordertoresetthevalueoftheinputelement,wetakeadvantageofthetwo-waydata-bindingthatwedeclaredandsetthevalueoftheinputpropertytotheemptystring.

NoteMovingtheentirelogicfromthetemplatesofthecomponentstotheircontrollersbringsalotofbenefits,suchasimprovedtestability,maintainability,codereuse,andclarity.

TheprecedingcodeiscompatiblewiththeWebWorkersenvironment,sincetheNgModeldirectiveisbasedonanabstractionthatdoesnotmanipulatetheDOMdirectly,butinstead,underthehood,exchangesmessagesasynchronouslywiththemainUIthread.

Torecap,wecansaythatwhilerunningapplicationsinthecontextofWebWorkers,weneedtokeepthefollowingtwothingsinmind:

Weneedtouseadifferentbootstrapprocess.WeshouldnotaccesstheDOMdirectly.

Typicalscenariosthatviolatethesecondpointareasfollows:

ChangingtheDOMofthepagebyselectinganelementandmanipulatingitdirectlywiththebrowser’snativeAPIsorathird-partylibrary.AccessingnativeelementsinjectedbyusingElementRef.Creatingareferencetoanelementinthetemplateandpassingitasanargumenttomethods.Directlymanipulatinganelementreferencedwithinthetemplate.

Inallthesescenarios,weneedtousetheAPIsprovidedbyAngular.Ifwebuildourapplicationsaccordingtothispractice,wewillbenefitnotonlyfrombeingabletoruntheminWebWorkers,butalsofromincreasingthecodereuseincasewewanttousethemacrossdifferentplatforms.

Keepingthisinmindwillallowustotakeadvantageofserver-siderendering.

Page 357: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 358: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Initialloadofasingle-pageapplicationInthissection,wewillexplorewhatserver-siderenderingis,whyweneeditinourapplications,andhowwecanuseitwithAngular2.

Forourpurposes,we’llexplainthetypicalflowofeventswhenauseropensaSPAimplementedinAngular2.First,we’lltracetheeventswiththeserver-siderenderingdisabled,andafterthat,we’llseehowwecanbenefitfromthisfeaturebyenablingit.OurexamplewillbeillustratedinthecontextofHTTP1.1.

Thisimageshowsthefirstrequestbythebrowserandthecorrespondingserver’sresponsewhenloadingatypicalSPA.TheresultthattheclientwillseeinitiallyistheinitialcontentoftheHTMLpagewithoutanyrenderedcomponents.

Let’ssupposethatwedeploytheto-doapplicationwebuiltinChapter4,GettingStartedwithAngular2ComponentsandDirectivestoawebserverthathasthehttps://example.comdomainassociatedwithit.

Oncetheusernavigatestohttps://example.com/,thebrowserwillopenanewHTTPGETrequest,fetchingtherootresource(/).Whentheserverreceivestherequest,itwillrespondwithanHTMLfilethat,inourcase,willlooksomethinglikethis:

<!DOCTYPEhtml>

<htmllang="en">

<head>

<title>SwitchingtoAngular2</title>

<linkrel="stylesheet"href="bootstrap.min.css">

</head>

<body>

<app>Loading…</app>

<scriptsrc="es6-shim.min.js"></script>

<scriptsrc="Reflect.js"></script>

<scriptsrc="system.src.js"></script>

<scriptsrc="angular2-polyfills.js"></script>

<scriptsrc="Rx.min.js"></script>

Page 359: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

<scriptsrc="angular2.js"></script>

<scriptsrc="router.js"></script>

<scriptsrc="http.min.js"></script>

<script>…</script>

</body>

</html>

Thebrowserwillreceivethiscontentasthebodyoftheresponse.Whenthemarkupisrenderedontothescreen,allthattheuserwillseeisthelabel:Loading….

Inthenextstep,thebrowserwillfindallthereferencesintheHTMLfile’sexternalresources,suchasstylesandscripts,andstartdownloadingthem.Inourcase,someofthemarebootstrap.css,es6-shim.min.js,Reflect.js,system.src.js,andangular2-polyfills.js.

Onceallthereferencedresourcesareavailable,therestillwon’tbeanysignificantvisualprogressfortheuser(exceptifthestylesfromthedownloadedCSSfileareappliedtothepage).Thiswon’tchangeuntiltheJavaScriptvirtualmachineprocessesallthereferencedscriptsrelatedtotheapplication’simplementation.Atthispoint,AngularwillknowwhichcomponentneedstoberenderedbasedonthecurrentURLandbootstrap’sconfiguration.

Ifthecomponentassociatedwiththepageisdefinedinaseparatefileoutsideofourmainapplicationbundle,theframeworkwillneedtodownloadittogetherwithitsentiredependencygraph.Incasethetemplateandthestylesofthecomponentareexternalized,Angularwillneedtodownloadthemaswellbeforeitisabletorendertherequestedpage.

Rightafterthis,theframeworkwillbeabletocompilethetemplateassociatedwiththetargetcomponentandrenderthepage.

Inthepreviousscenario,therearethefollowingtwomainpitfalls:

SearchenginesarenotthatgoodatindexingdynamiccontentgeneratedbyJavaScript.ThismeansthattheSEO(SearchEngineOptimization)ofourSPAwillsuffer.Incaseoflargeapplicationsand/orpoorInternetconnection,theuserexperiencewillbepoor.

Inthepast,wesolvedtheSEOissueintheapplicationsbuiltwithAngularJS1.xwithdifferentworkarounds,suchasusingheadlessbrowserforrenderingtherequestedpage,cachingitontothedisk,andlaterprovidingittosearchengines.However,there’samoreelegantsolution.

Page 360: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

InitialloadofaSPAwithserver-siderenderingAcoupleofyearsago,librariessuchasRendr,Derby,Meteor,andtheothersintroducedtheconceptofisomorphicJavaScriptapplications,whichwerelaterrenamedtouniversal.Inessence,universalapplicationscouldberunontheclientaswellasontheserver.SuchportabilityisonlypossibleinthecaseoflowcouplingbetweentheSPAandthebrowser’sAPIs.Thegreatestbenefitofthisparadigmisthattheapplicationcanbererenderedontheserverandlatersenttotheclient.

Universalapplicationsarenotframework-specific;wecantakeadvantageoftheminanyframeworkthatcanberunoutsideoftheenvironmentofthebrowser.Conceptually,thepracticeofserver-siderenderingisverysimilaracrossplatformsandlibraries;onlyitsimplementationdetailsmaydiffer.Forinstance,theAngular2Universalmodule,whichimplementsserver-siderendering,hassupportfornode.jsaswellasASP.NETthat,atthemomentofthiswriting,isstillworkinprogress.

TheprecedingimageshowstheresponsebytheservertotheinitialbrowserGETrequest.Thistime,incontrasttothetypicalscenarioofloadingaSPA,thebrowserwillgettherenderedcontentoftheHTMLpage.

Let’stracetheflowoftheeventsinthesameapplicationwiththeserver-siderenderingfeatureenabled.Inthiscase,oncetheserverreceivestheHTTPGETrequestbythebrowser,itwillruntheSPAontheserverinthenode.jsenvironment.AlltheDOMcallsaregoingtoberedirectedtoaserver-sideDOMimplementationandbeexecutedinthecontextoftheusedplatform.Similarly,alltheAJAXcallswiththehttpmodulewillbehandledbytheserver-sideimplementationofthemodule.Thisway,theapplicationwillnotmakeanydifference,whetheritisrunninginthecontextofthebrowserortheserver.

OncetherenderedversionoftheSPAisavailable,itcanbeserializedtoHTMLandsenttothebrowser.Thistime,duringtheapplication’sinitialization,insteadoftheLoading…label,theuserwillseethepagetheyrequestedrightaway.

Notethatatthispoint,theclientwillhavetherenderedversionoftheapplication,butall

Page 361: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

thereferencedexternalresources,suchasscriptsandstyles,stillneedtobeavailable.Thismeansthat,initially,noneoftheCSSstylesdeclaredintheexternalfileswillbeappliedandtheapplicationwillnotberesponsivetoanyuser-relatedinteractions,suchasthemouseandkeyboardevents.

NoteNotethatincasethescriptsareinlinedintotheserver-siderenderedpage,theapplicationwillberesponsivetouserevents.However,inliningbigchunksofJavaScriptisgenerallyconsideredasabadpractice,sinceitwillincreasethepage’ssizedramaticallyandpreventthescriptsfromcaching.Bothwillinfluencethenetworkperformance.

WhentheJavaScriptvirtualmachineprocessestheJavaScriptassociatedwiththepage,ourSPAwillbereadytouse.

Page 362: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Server-siderenderingwithAngular2Inthefirsthalfof2015,PatrickStapletonandJeffWhelpleyannouncedthattheystartedthedevelopmentofthemodule,Universal.Universalisalibrarythatallowsustobuilduniversal(alsocalledisomorphic)JavaScriptapplicationswithAngular2;inotherwords,itprovidesserver-siderenderingsupport.

ApplicationsbuiltwithAngular2andUniversalwillnotberesponsiveuntilalltheJavaScriptbelongingtotherequestedpageisprocessed.Thisisadrawbackthatwealreadymentioned,whichisvalidforalltheserver-siderenderedapplications.However,PatrickandJeffintroducedpreboot.js,whichisalightweightlibrarythatwillbeinlinedonthepagerenderedbytheserverandavailableaftertheinitialclientrequest.

Preboot.jshasseveralstrategiesforthemanagementofthereceivedclienteventsbeforetheapplicationhasbeencompletelyinitialized.Theyareasfollows:

Recordandplaybackevents.Respondimmediatelytoevents.Maintainfocuswhenapageisrerendered.Bufferclient-sidere-renderingforsmoothertransition.Freezepageuntilthebootstrapiscompleteifauserclicksonabutton.

Atthemomentofthiswriting,theUniversalmoduleisstillbeingactivelydeveloped.However,youcangiveitatryusingtheAngular2universalstarterathttps://github.com/angular/universal-starter.

Page 363: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 364: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

EnhancingourdevelopmentexperienceOurexperienceasdeveloperscanbeenhancedintermsofproductivityorbyallowingustohavemorefunwhileworkingonourprojects.Thiscanbeachievedwithallthetools,IDEs,texteditors,andmorethatweuseonadailybasis.Inthissection,we’llbrieflytakealookatpopularIDEsandtexteditorsthatwecanusefortakingadvantageofthestaticcodeanalysisfeaturesthatAngular2provides.

Inthesecondpartofthissection,we’llseewhathotreloadingisandhowwecantakeadvantageofitduringthedevelopmentofAngular2applications.

Page 365: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

TexteditorsandIDEsAswealreadymentionedatthebeginningofthebook,thecoreteamputgreateffortintoenhancingthetoolingsupportinAngular2.Firstofall,theframeworkisbuiltwithTypeScript,whichnaturallyallowsustousestatictypingduringourdevelopmentprocess.SomeofthetexteditorsandIDEsthathavegreatTypeScriptsupportareasfollows:

IntelliJIdea:Ageneral-purposeIDEbyJetBrains.WebStorm:AnIDEspecializedforwebdevelopmentbyJetBrains.VSCode:Across-platformtexteditorwritteninTypeScriptanddevelopedbyMicrosoft.SublimeText:Across-platformtexteditor.Atom:Across-platformtexteditor.

Recently,JetBrainsannouncedadvancedAngular2supportinIntelliJIdeaandWebStorm,whichsupportsautocompletionforcomponentsandbindings.

AlthoughnotallthementionedIDEsandtexteditorshaveAngular2-specificsupportatthemomentofthiswriting,Angular2comeswithagreatdesign.Itallowsustoperformadvancedstaticcodeanalysisontheapplication’scodebaseforthedevelopmentofsophisticatedrefactoringandproductivitytoolsinthenearfuture.Untilthen,Angular2atleastprovidestoolingsupportasgoodanyotherJavaScriptframeworkinthemarket.

Page 366: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

HotreloadingHotreloading(orhotloading)isapracticethatgotpopularintheworldofpurelyfunctionaluserinterfacesinlibrariessuchasOm(usedwithClojureScript)andReact.

WhendevelopingaSPA,itisquiteannoyingtorefreshyourbrowseraftereachsmallchangeofastyle,view,orevenacomponent.That’swhyacoupleofyearsago,atoolwasdevelopedcalledlivereload.Livereloadwatchesthefilesofourapplication,andwhenitdetectsachangeinanyofthem,itsendsamessagetothebrowsertorefreshthepage.Usually,theconnectionestablishedbetweenthelivereloadserverandtheclientisthroughWebSockets,sincetheserverneedstosendpushnotifications.Althoughthistoolworksgreatinsomecases,ithasonebigdisadvantage:oncethepageisrefreshed,allofthestatecollectedduringthedeveloper’sinteractionwillbelost.

Forinstance,imagineascenariowhereyou’reworkingonanapplicationwithacomplexview.Younavigatethroughafewpages,fillinforms,andsetthevaluestoinputfields,andthen,unexpectedly,youfindanissue.YougotoyourtexteditororIDEandfixtheissue;thelivereloadserverdetectsachangeinyourproject’srootandsendsanotificationtothebrowserinordertorefreshthepage.Now,you’rebacktotheinitialstateoftheapplicationandyouneedtogothroughallthesestepsinordertoreachthesamepointbeforetherefresh.

Incontrasttolivereloading,inmostcases,hotreloadingcaneliminatethestatelost.Let’stakeabrieflookathowitworks.

Atypicalimplementationofahotreloaderhastwomainmodules:aclientandaserver.Incontrasttotheserverinlivereloading,thehotreloaderservernotonlywatchesthefilesystemforchanges,butalsotakesthecontentofthechangedfileandsendsittothebrowser.Oncethebrowserreceivesthemessagesentbytheserver,itcanswapthepreviousimplementationofthechangedunitwiththenewone.Afterthis,theviewaffectedbythechangecanbererenderedinordertovisuallyreflectthechange.Sincetheapplicationdoesn’tloseitsstate,wecancontinuefromthepointwe’vereachedwiththenewversionofthechangedcodeunit.

Unfortunately,itisnotalwayspossibletodynamicallyswaptheimplementationsofallyourcomponentsusingthisstrategy.Ifyouupdateapieceofcodethatholdsthatholdsapplicationstate,youmayneedtorefreshthepagemanually.

HotreloadinginAngular2Atthetimeofwriting,thereisaworkingprototypeofAngular2hotreloaderthatcanbetestedwiththeangular2-seeddescribedintheAngular2quickstarterssection.Theprojectisinactivedevelopment,sotherearealotofimprovementsontheroadmap.Butitalreadyprovidesitscorefunctionality,whichcaneasethedevelopmentexperiencesignificantly.

Page 367: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 368: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Bootstrappingaprojectwithangular-cliDuringAngularConnect2015,BradGreenandIgorMinar,partoftheAngularteam,announcedangular-cli—aCLI(command-lineinterface)tooltoeasestartingandmanagingAngular2applications.ForthosewhohaveusedRubyonRails,theideabehindtheCLItoolmightbefamiliar.Thebasicpurposeofthetoolistoallowthequickbootstrappingofnewprojectsandscaffoldingofnewdirectives,components,pipes,andservices.

Atthetimeofwriting,thetoolisstillintheearlystageofdevelopment,sowe’lldemonstrateonlyitsbasicusage.

Page 369: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Usingangular-cliInordertoinstalltheCLItool,runthefollowingcommandinyourterminal:

npminstall-gangular-cli

Rightafterthis,theglobalngcommandwillappearinyour$PATH.ForcreatinganewAngular2project,usethefollowing:

#Maytakeawhile,dependingonyourInternetconnection

ngnewangular-cli-project

cdangular-cliproject

ngserve

Theprecedingcommandswilldothefollowing:

CreateanewAngular2projectandinstallallofitsnode.jsdependencies.Enteryourproject’sdirectory.Startadevelopmentwebserverthatwillletyouopentheapplicationyoujustcreatedinyourwebbrowser.

Forfurtherreading,takealookattheproject’srepositorylocatedathttps://github.com/angular/angular-cli.

Page 370: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 371: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Angular2quickstartersAlthoughAngular2CLIisgoingtobeamazing,atthemomentofthiswriting,itisstillataveryearlystageofdevelopment.It’sbuild-toolagnostic,whichmeansthatitdoesn’tprovideanybuildsystem.Luckily,therearealotofstarterprojectsdevelopedbythecommunitythatcanprovideagreatstartingpointforournextAngular2project.

Page 372: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Angular2seedIncaseyouenjoyGulpandstatictyping,youcangiveatrytotheangular2-seedproject.ItishostedonGitHubatthefollowingURL:https://github.com/mgechev/angular2-seed.

TheAngular2seedprovidesthefollowingkeyfeatures:

Advanced,ready-to-go,easy-to-extend,modular,andstaticallytypedbuildsystemusingGulp.Productionanddevelopmentbuilds.SampleunittestswithJasmineandKarma.End-to-endtestswithProtractor.AdevelopmentserverwithLivereload.Experimentalhotreloadingsupport.Followingthebestpracticesforyourapplications’andfiles’organization.ManagerfortheTypeScript-relatedtypedefinitions.

Thecodedistributedwiththebookisbasedonthisseedproject.

Forangular2-seed,youneedtohavenode.js,npm,andGitinstalled,andyouneedtorunthefollowinglistofcommands:

gitclone--depth1https://github.com/mgechev/angular2-seed.git

cdangular2-seed

npminstall

npmstart

Afteryourunthesecommands,yourbrowserwillbeautomaticallyopenedwiththehomepageoftheseed.OnthechangeofanyoftheTypeScriptfiles,thecodewillbeautomaticallytranspiledtoJavaScriptandyourbrowserwillberefreshed.

Theproductionbuildisconfigurable,butbydefault,itproducesasinglebundlethatcontainsaminifiedversionoftheapplicationandallthereferencedlibraries.

Page 373: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Angular2WebpackstarterIfyoupreferdeclarativeandminimalisticbuildswithWebpack,youcanuseangular2-webpack-starter.ItisastarterprojectdevelopedbyAngularClassandhostedonGitHub.YoucanfinditatthefollowingURL:https://github.com/AngularClass/angular2-webpack-starter.

Thisstarterprovidesthefollowingfeatures:

ThebestpracticesinfileandapplicationorganizationforAngular2.Ready-to-gobuildsystemusingWebpackforworkingwithTypeScript.TestingAngular2codewithJasmineandKarma.CoveragewithIstanbulandKarma.End-to-endAngular2codeusingProtractor.TypemanagerwithTypings.

Inordertogiveitatry,youneedtohavenode.js,npm,andgitinstalled,andyouneedtorunthefollowingcommands:

gitclone--depth1https://github.com/angularclass/angular2-webpack-

starter.git

cdangular2-webpack-starter

npminstall

./node_modules/.bin/typingsinstall

npmstart

Page 374: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What
Page 375: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

SummaryWestartedthisbookbyintroducingthereasonsbehindthedevelopmentofAngular2,whichwasfollowedbyaconceptualoverviewthatgaveusageneralideaaboutthebuildingblocksthattheframeworkprovidesforapplicationdevelopment.Inthenextstep,wedidaTypeScriptcrashcoursethatpreparedusforChapter4,GettingStartedwithAngular2ComponentsandDirectiveswherewewentdeepintoAngular’sdirectives,components,andchangedetection.

InChapter5,DependencyInjectioninAngular2weexplainedthedependencyinjectionmechanismandsawhowwecanmanagetherelationsbetweenthedifferentcomponentsbyusingit.Thenextchaptersexplainedtoushowwecanbuildformsandpipes,andtakeadvantageofAngular2’scomponent-basedrouter.

Bycompletingthecurrentchapter,wefinishedourjourneyintotheframework.Atthemomentofthiswriting,thedesigndecisionsandtheideasbehindAngular2’scorearesolidandfinalized.Althoughtheframeworkisstillbrandnew,inthepastcoupleofmonthsitsecosystemreachedalevelthatwecandevelopproduction-ready,high-performance,SEO-friendlyapplications,andontopofthis,haveagreatdevelopmentexperienceexploitingstatictypingandhotreloading.

Page 376: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

IndexA

accessmodifierspublic/Usingaccessmodifiersprivate/Usingaccessmodifiersprotected/Usingaccessmodifiers

ambienttypedefinitionsusing/Usingambienttypedefinitionspredefinedambienttypedefinitions,using/Usingambienttypedefinitions,Customambienttypedefinitionscustom/Customambienttypedefinitionsts.dfiles,defining/Definingts.dfiles

AMD(AsynchronousModuleDefinition)/WritingmodularcodewithES2015angular-cli

used,forbootstrappingproject/Bootstrappingaprojectwithangular-cliusing/Usingangular-cliURL/Usingangular-cli

Angular2conceptualoverview/AconceptualoverviewofAngular2components/ComponentsinAngular2route,definitionsyntax/Angular2routedefinitionsyntaxHelloworld!application,building/TheHelloworld!applicationinAngular2playingwith/PlayingwithAngular2andTypeScriptDependencyInjection(DI)/DependencyInjectioninAngular2model-drivenforms,developing/Developingmodel-drivenformsinAngular2HTTPmodule,exploring/ExploringtheHTTPmoduleofAngularHTTPmodule,using/UsingAngular’sHTTPmodulebuilt-inpipes,using/UsingAngular’sbuilt-inpipesAsyncPipe,using/UsingAngular’sAsyncPipeandWebWorkers/WebWorkersandAngular2hotreloading/HotreloadinginAngular2about/Angular2quickstartersGulpseed/Angular2seedWebpackstarter/Angular2Webpackstarter

Angular2andTypeScriptindex,defining/Diggingintotheindex

Angular2directivesusing/UsingAngular2directivesngFordirective/ThengFordirectivedefining/DefiningAngular2directivesinputs,setting/Settingthedirective’sinputsconstructor,defining/Understandingthedirective’sconstructor

Page 377: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

encapsulation/BetterencapsulationofdirectivesAngular2forms

using/UsingAngular2formsmodel-drivenapproach/UsingAngular2formstemplate-drivenforms,developing/Developingtemplate-drivenformstemplate-drivenform’smarkup,exploring/Diggingintothetemplate-drivenform’smarkupbuilt-informvalidators,using/Usingthebuilt-informvalidatorscustomcontrolvalidators,defining/Definingcustomcontrolvalidatorsselectinputs,using/UsingselectinputswithAngularNgFormdirective,using/UsingtheNgFormdirectiveused,fortwo-waydata-binding/Two-waydata-bindingwithAngular2data,storing/Storingtheformdata

Angular2routerexploring/ExploringtheAngular2routerrootcomponent,defining/Definingtherootcomponentandbootstrappingtheapplicationapplication,bootstrapping/DefiningtherootcomponentandbootstrappingtheapplicationPathLocationStrategy,using/UsingPathLocationStrategyroutes,configuringwith@RouteConfig/Configuringrouteswith@RouteConfigrouterLink,using/UsingrouterLinkandrouter-outletrouter-outlet,using/UsingrouterLinkandrouter-outletlazy-loading,withAsyncRoute/Lazy-loadingwithAsyncRoute

angular2-seedprojectURL/Angular2seed

AngularJS1.xabout/LessonslearnedfromAngularJS1.xinthewildcontrollers/Controllersscopeobject/Scopedependencyinjection(DI)/DependencyInjectionserver-siderendering/Server-siderenderingsingle-pageapplications/Applicationsthatscaletemplates/Templateschangedetection/Changedetection,AngularJS1.xchangedetectionchangedetection,enhancing/EnhancingAngularJS1.x’schangedetection

applicationrunninginWebWorkers,bootstrapping/BootstrappinganapplicationrunninginWebWorkermigrating,toWebWorker/MigratinganapplicationtoWebWorker

AsyncPipeusing/UsingAngular’sAsyncPipeusing,withobservables/UsingAsyncPipewithobservables

Page 378: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

AsyncRouteused,forlazy-loading/Lazy-loadingwithAsyncRoute

Page 379: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Bblockscope

used,fordefiningvariables/Definingvariableswithblockscopebuilt-inchangedetection

dynamicchangedetection/ChangedetectionJITchangedetection/Changedetection

built-indirectives,Angular2using/UsingAngular2’sbuilt-indirectives

built-informvalidatorsusing/Usingthebuilt-informvalidatorsminlength/Usingthebuilt-informvalidatorsmaxlength/Usingthebuilt-informvalidators

built-inpipesusing/UsingAngular’sbuilt-inpipesCurrencyPipe/UsingAngular’sbuilt-inpipesDatePipe/UsingAngular’sbuilt-inpipesDecimalPipe/UsingAngular’sbuilt-inpipesJsonPipe/UsingAngular’sbuilt-inpipesLowerCasePipe/UsingAngular’sbuilt-inpipesUpperCasePipe/UsingAngular’sbuilt-inpipesPercentPipe/UsingAngular’sbuilt-inpipesSlicePipe/UsingAngular’sbuilt-inpipesAsyncPipe/UsingAngular’sbuilt-inpipes

Page 380: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Cchangedetection

about/Changedetection,AconceptualoverviewofAngular2,Changedetectionexample/ClassicalchangedetectioninAngularJS1.x/AngularJS1.xchangedetectioninzone.js/Inthezone.jssimplifieddata-flow/Simplifieddataflowenhancing,inAngularJS1.x/EnhancingAngularJS1.x’schangedetectiondefining/Understandingandenhancingthechangedetectionenhancing/Understandingandenhancingthechangedetectionorderofexecution/Theorderofexecutionofthechangedetectorsstrategies/Changedetectionstrategiesperformanceboosting,withimmutabledataandOnPush/PerformanceboostingwithimmutabledataandOnPushimmutabledatastructures,usinginAngular/UsingimmutabledatastructuresinAngular

childinjectorsabout/Childinjectorsandvisibilitydependencies,configuring/Configuringdependencieselementinjectors/Introducingtheelementinjectors

Codersrepositoryapplicationdeveloping/Developingthe“Codersrepository”applicationviews/Developingthe“Codersrepository”applicationbootstrapping/Definingtherootcomponentandbootstrappingtheapplication

CommonJS/WritingmodularcodewithES2015component-basedrouter

about/Understandingthenewcomponent-basedrouterAngular2route,definitionsyntax/Angular2routedefinitionsyntax

Componentclassabout/GettingtoknowAngular2components

componentsabout/AconceptualoverviewofAngular2,GettingtoknowAngular2componentscomposing/ComponentsinactioninAngular2/ComponentsinAngular2DependencyInjection(DI),using/UsingDIwithcomponentsanddirectivesDependencyInjection(DI),exploringwith/ExploringDIwithcomponents

Compositeclassabout/GettingtoknowAngular2components

containerabout/Configuringaninjector

contentchildren

Page 381: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

about/Nestingcomponentscontentprojection,Angular2

defining/ExplainingAngular2’scontentprojectionabout/BasiccontentprojectioninAngular2multiplecontentchunks,projecting/Projectingmultiplecontentchunkscomponents,nesting/NestingcomponentsViewChildren,using/UsingViewChildrenandContentChildrenContentChildren,using/UsingViewChildrenandContentChildrenViewChild,versusContentChild/ViewChildversusContentChild

controllerassyntaxabout/Scope

controllersabout/Controllers

controllers,componentimplementing/Implementingthecomponent’scontrollers

controlvalidatorscomposition,using/Usingcompositionofcontrolvalidators

CreateRetrieveUpdateandDelete(CRUD)/Developingtemplate-drivenformsCSP(Content-Security-Policy)

about/UnderstandingandenhancingthechangedetectionCSSclasses

about/Diggingintothetemplate-drivenform’smarkupng-untouched/Diggingintothetemplate-drivenform’smarkupng-touched/Diggingintothetemplate-drivenform’smarkupng-pristine/Diggingintothetemplate-drivenform’smarkupng-dirty/Diggingintothetemplate-drivenform’smarkupng-valid/Diggingintothetemplate-drivenform’smarkupng-invalid/Diggingintothetemplate-drivenform’smarkup

customcontrolvalidatorsdefining/Definingcustomcontrolvalidators

Page 382: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Ddata

transforming,pipesused/Transformingdatawithpipesdecorators

URL/Meta-programmingwithES2016decoratorsDefinitelyTyped

URL/Usingambienttypedefinitionsdependencies,childinjectors

configuring/Configuringdependenciesselfdecorator,using/Usingthe@Selfdecoratorselfinjector,skipping/Skippingtheselfinjectoroptionaldependencies,using/Havingoptionaldependenciesmultiproviders,using/Usingmultiproviders

dependencyinjection(DI)about/DependencyInjection

DependencyInjection(DI)needfor/WhydoIneedDependencyInjection?inAngular2/DependencyInjectioninAngular2benefits/BenefitsofDIinAngular2using,withcomponentsanddirectives/UsingDIwithcomponentsanddirectivesexploring,withcomponents/ExploringDIwithcomponentsusing,withES5/UsingAngular’sDIwithES5

differsabout/AconceptualoverviewofAngular2

DImechanismabout/AconceptualoverviewofAngular2

directivesabout/AconceptualoverviewofAngular2modifying/ChangingdirectivesDependencyInjection(DI),using/UsingDIwithcomponentsanddirectives

directivessyntaxsemantics,defining/Improvedsemanticsofthedirectivessyntaxvariables,declaringinsidetemplate/Declaringvariablesinsideatemplatesyntaxsugarused,intemplates/Usingsyntaxsugarintemplates

Domain-SpecificLanguage(DSL)about/UsingAngular’sDIwithES5

DomainSpecificLanguage(DSL)about/Templates,Changingdirectives

dynamicchangedetectionabout/Changedetection

Page 383: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

EECMAScript

evolution/TheevolutionofECMAScriptWebComponents/WebComponentsWebWorkers/WebWorkers

ECMAScript5(ES5)about/Changingdirectives

ECMAScript2015(ES2015)about/TheevolutionoftheWeb–timeforanewframework

elementinjectorsabout/Introducingtheelementinjectorsproviders,declaring/DeclaringprovidersfortheelementinjectorsDependencyInjection(DI),exploringwithcomponents/ExploringDIwithcomponentsviewProviders,versusproviders/viewProvidersversusproviders

enumtypesabout/TheEnumtypes

environment,Angular2settingup/Settingupourenvironmentreferences/Settingupourenvironmentprojectrepository,installing/InstallingourprojectrepositoryURL,forissues/Installingourprojectrepository

ES5DependencyInjection(DI),usingwith/UsingAngular’sDIwithES5

ES2015TypeScriptsyntax/TypeScriptsyntaxandfeaturesintroducedbyES2015andES2016TypeScriptfeatures/TypeScriptsyntaxandfeaturesintroducedbyES2015andES2016arrowfunctions/ES2015arrowfunctionsandES2016classes,using/UsingtheES2015andES2016classesmodularcode,writingwith/WritingmodularcodewithES2015modulesyntax,using/UsingtheES2015modulesyntaximplicitasynchronousbehavior/Takingadvantageoftheimplicitasynchronousbehavioraliases,using/Usingaliasesmoduleexports,importing/Importingallthemoduleexportsdefaultexports/Defaultexportsmoduleloader/ES2015moduleloaderandES2016,recap/ES2015andES2016recap

ES2016decoratorsmeta-programmingwith/Meta-programmingwithES2016decoratorsconfigurabledecorators,using/Usingconfigurabledecorators

Page 384: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Ffactories

using/Usingexistingprovidersdefining,forinstantiatingservices/Definingfactoriesforinstantiatingservices

forwardreferencesabout/Introducingforwardreferences

Page 385: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Ggenericcode

writing,typeparametersused/Writinggenericcodebyusingtypeparametersgenericfunctions,using/Usinggenericfunctionsmultipletypeparameters,having/Havingmultipletypeparameters

genericviewsdefining,withTemplateRef/DefininggenericviewswithTemplateRef

GitHubAPItokenreferencelink/ExploringtheHTTPmoduleofAngular

GoogleClosureCompiler/BettersupportbytexteditorsandIDEs

Page 386: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

HHelloworld!application

defining,inAngular2/TheHelloworld!applicationinAngular2hostinjectors

about/Introducingtheelementinjectors,ExploringDIwithcomponentshotreloading

about/HotreloadinginAngular2/HotreloadinginAngular2

HTTPmoduleexploring/ExploringtheHTTPmoduleofAngularusing/UsingAngular’sHTTPmodule

Page 387: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

IIDEs/TexteditorsandIDEsimplicitasynchronousbehavior,ES2015/Takingadvantageoftheimplicitasynchronousbehaviorinjector

about/Configuringaninjectorconfiguring/Configuringaninjectordependencyresolution,withgeneratedmetadata/Dependencyresolutionwithgeneratedmetadatainstantiating/Instantiatinganinjectorforwardreferences/Introducingforwardreferencesproviders,configuring/Configuringprovidersfactories,using/Usingexistingprovidersfactories,definingforinstantiatingservices/Definingfactoriesforinstantiatingserviceschildinjectors/Childinjectorsandvisibilityhierarchy,building/Buildingahierarchyofinjectors

inlinecachingreferencelink/Changedetection

interfacesabout/Defininginterfacesinheritance/Interfaceinheritancemultipleinterfaces,implementing/Implementingmultipleinterfaces

inversionofcontrol(IoC)about/DependencyInjection

isomorphic/Server-siderenderingwithAngular2

Page 388: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

JJITchangedetection

about/Changedetection

Page 389: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

LLeafclass

about/GettingtoknowAngular2componentslessverbosecode

writing,withTypeScriptstypeinference/WritinglessverbosecodewithTypeScript’stypeinferencebestcommontype/Bestcommontypecontextualtypeinference/Contextualtypeinference

lifecycle,componenthookinginto/Hookingintothecomponent’slifecycle

livereload/Hotreloading

Page 390: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

MMassiveViewController(MVC)

about/Controllersmodel-drivenforms,Angular2

developing/Developingmodel-drivenformsinAngular2controlvalidatorscomposition,using/Usingcompositionofcontrolvalidators

Model-View-Controller(MVC)about/GettingtoknowAngular2components

Model-View-ViewModel(MVVM)about/GettingtoknowAngular2components

Model-View-Whatever(MVW)about/Changedetection

ModelViewController(MVC)about/Controllers

ModelViewPresenter(MVP)about/Controllers

ModelViewViewModel(MVVM)about/Controllers

ModelViewWhatever(MVW)about/Controllers

multiprovidersusing/Usingmultiproviders

Page 391: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Nn

URL/Settingupourenvironmentnestedroutes

defining/DefiningnestedroutesNgFormdirective

using/UsingtheNgFormdirectivenode.js

URL/UsingTypeScriptNodePackageManager(npm)/UsingTypeScript

used,forinstallingTypeScript/InstallingTypeScriptwithnpmnvm

URL/Settingupourenvironment

Page 392: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Oobject-oriented(OO)paradigm/UsingtheES2015andES2016classesObjecttypes

Arraytypes/TheArraytypesFunctiontypes/TheFunctiontypes

operationabout/GettingtoknowAngular2components

orderofexecutiontracing/Theorderofexecution

Page 393: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Pparameterizedviews

defining/DefiningparameterizedviewsPathLocationStrategy

using/UsingPathLocationStrategypipes

about/AconceptualoverviewofAngular2,Pipesdefining/Definingpipesused,fordatatransformations/Transformingdatawithpipesstatelesspipes,developing/Developingstatelesspipesbuilt-inpipes,using/UsingAngular’sbuilt-inpipesstatefulpipes,developing/Developingstatefulpipes

preboot.js/Server-siderenderingwithAngular2primitivetypes

about/UnderstandingthePrimitivetypesproviders

about/Configuringaninjectorconfiguring/Configuringprovidersexistingproviders,using/Usingexistingprovidersdeclaring,forelementinjectors/DeclaringprovidersfortheelementinjectorsversusviewProviders/viewProvidersversusproviders

Page 394: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

R@RouteConfig

used,forrouteconfiguration/Configuringrouteswith@RouteConfigrootcomponent

defining/Definingtherootcomponentandbootstrappingtheapplicationroute

definitionsyntax/Angular2routedefinitionsyntaxrouter-outlet

using/UsingrouterLinkandrouter-outletrouterLink

using/UsingrouterLinkandrouter-outletRxJSGitHubrepository

about/TheHelloworld!applicationinAngular2URL/TheHelloworld!applicationinAngular2

Page 395: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Sscopeobject

about/ScopeSearchEngineOptimization(SEO)

about/Server-siderenderingselectinputs

using,withAngular2forms/UsingselectinputswithAngularselfdecorator

using/Usingthe@Selfdecoratorselfinjector

skipping/SkippingtheselfinjectorSEO(SearchEngineOptimization)

andUI/Initialloadofasingle-pageapplicationserver-siderendering

about/Server-siderenderingservices

about/AconceptualoverviewofAngular2,Understandingservicesinstantiating,withfactories/Definingfactoriesforinstantiatingservices

single-pageapplicationinitialload/Initialloadofasingle-pageapplicationinitialload,withenabledserver-siderendering/InitialloadofaSPAwithserver-siderenderingserver-siderendering,withAngular2/Server-siderenderingwithAngular2

single-pageapplicationsabout/Applicationsthatscale

single-pageapplications(SPA)about/Understandingthenewcomponent-basedrouter

statefulpipesdeveloping/Developingstatefulpipesusing/Usingstatefulpipes

statelesspipesdeveloping/Developingstatelesspipes

statictypingabout/Takingadvantageofstatictypingexplicittypedefinitions,using/Usingexplicittypedefinitionstypeany/Thetypeanyprimitivetypes/UnderstandingthePrimitivetypesenumtypes/TheEnumtypesObjecttypes/UnderstandingtheObjecttypesArraytypes/TheArraytypesFunctiontypes/TheFunctiontypesclasses,defining/Definingclassesaccessmodifiers,using/Usingaccessmodifiers

Page 396: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

interfaces,defining/Defininginterfacesinterfaceinheritance/Interfaceinheritancemultipleinterfaces,implementing/Implementingmultipleinterfaces

storeddeveloperslisting/Listingallthestoreddevelopers

subtyping/Defininginterfaces

Page 397: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Ttemplate-drivenforms

developing/Developingtemplate-drivenformsmarkup,exploring/Diggingintothetemplate-drivenform’smarkup

TemplateRefgenericviews,definingwith/DefininggenericviewswithTemplateRef

templatesabout/Templates

texteditorsandIDEs/TexteditorsandIDEs

timetolive(TTL)about/Applicationsthatscale

Todoapplicationcomponents/Findingoutdirectives’inputsandoutputs

tokenabout/Configuringaninjector

transpilationabout/TheevolutionofECMAScript

TransportLayerSecurity(TLS)about/Definingfactoriesforinstantiatingservices

two-waydata-bindingusing,withAngular2/Two-waydata-bindingwithAngular2

typeinferenceused,forwritinglessverbosecode/WritinglessverbosecodewithTypeScript’stypeinference

typeparametersused,forwritinggenericcode/Writinggenericcodebyusingtypeparametersgenericfunctions,using/Usinggenericfunctionsmultipletypeparameters,having/Havingmultipletypeparameters

types,TypeScriptabout/Thetypeanyprimitivetypes/Thetypeanyuniontypes/Thetypeanyobjecttypes/Thetypeanytypeparameters/Thetypeany

TypeScriptabout/IntroductiontoTypeScriptcompile-timetypechecking/Compile-timetypecheckingtexteditorsandIDEs,support/BettersupportbytexteditorsandIDEsbenefits/There’sevenmoretoTypeScriptusing/UsingTypeScript,TheHelloworld!applicationinAngular2installing,npmused/InstallingTypeScriptwithnpmprogram,running/RunningourfirstTypeScriptprogram

Page 398: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

syntax,byES2015andES2016/TypeScriptsyntaxandfeaturesintroducedbyES2015andES2016features,byES2015andES2016/TypeScriptsyntaxandfeaturesintroducedbyES2015andES2016ES2015arrowfunctions/ES2015arrowfunctionsES2015andES2016classes,using/UsingtheES2015andES2016classesvariables,definingwithblockscope/Definingvariableswithblockscopedecorators/FurtherexpressivenesswithTypeScriptdecoratorsplayingwith/PlayingwithAngular2andTypeScript

Page 399: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

UUniversal/Server-siderenderingwithAngular2universalstarter

URL/Server-siderenderingwithAngular2useractions

handling/Handlinguseractionsdirectives’inputandoutput,using/Usingadirectives’inputsandoutputsdirectives’inputandoutput,findingout/Findingoutdirectives’inputsandoutputscomponent’sinputandoutput,defining/Definingthecomponent’sinputsandoutputsinput,passing/Passinginputsandconsumingtheoutputsoutput,consuming/Passinginputsandconsumingtheoutputseventbubbling/Eventbubblinginputandoutputofdirective,renaming/Renamingtheinputsandoutputsofadirectivealternativesyntax,fordefininginputandoutput/Analternativesyntaxtodefineinputsandoutputs

Page 400: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Vviewchildren

about/Nestingcomponentsviewencapsulation,component

defining/Introducingthecomponent’sviewencapsulationviewProviders

versusproviders/viewProvidersversusprovidersviews,Codersrepositoryapplication

basicdetails/Developingthe“Codersrepository”application

Page 401: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

WWeb

evolution/TheevolutionoftheWeb–timeforanewframeworkWebComponents

about/TheevolutionoftheWeb–timeforanewframeworkevolution/WebComponents

WebpackstarterURL/Angular2Webpackstarter

WebWorkersapplications,running/RunningapplicationsinWebWorkersabout/RunningapplicationsinWebWorkersandAngular2/WebWorkersandAngular2application,bootstrapping/BootstrappinganapplicationrunninginWebWorkerandUI/BootstrappinganapplicationrunninginWebWorkerapplication,migratingto/MigratinganapplicationtoWebWorkercompatible,applicationcreating/MakinganapplicationcompatiblewithWebWorkers

WebWorkersabout/TheevolutionoftheWeb–timeforanewframework,WebWorkers

Page 402: dl.ebooksworld.ir€¦ · Table of Contents Switching to Angular 2 Credits Foreword About the Author About the Reviewers eBooks, discount offers, and more Why subscribe? Preface What

Zzone.js

changedetection/Inthezone.js