itech.pkitech.pk/uploads/attachments/1495119359.pdf · 1.1 1.2 1.3 2.1 2.1.1 2.1.1.1 2.1.1.2...

478

Upload: others

Post on 28-May-2020

7 views

Category:

Documents


0 download

TRANSCRIPT

  • 1.1

    1.2

    1.3

    2.1

    2.1.1

    2.1.1.1

    2.1.1.2

    2.1.1.3

    2.1.1.4

    2.1.1.5

    2.1.1.6

    2.1.1.7

    2.1.1.8

    2.1.1.9

    2.1.1.10

    2.1.2

    2.1.2.1

    2.1.2.2

    2.1.2.3

    2.1.2.4

    2.1.2.5

    2.1.2.6

    2.1.2.7

    2.1.2.8

    2.1.2.9

    2.1.2.10

    2.1.2.11

    2.1.2.12

    2.1.2.13

    2.1.2.14

    TableofContentsIntroduction

    License

    WhyAngular?

    EcmaScript6andTypeScriptFeatures

    ES6

    Classes

    Refresheron'this'

    ArrowFunctions

    TemplateStrings

    Inheritance

    Delegation

    ConstantsandBlockScopedVariables

    ...spreadand...rest

    Destructuring

    Modules

    TypeScript

    GettingStartedWithTypeScript

    WorkingWithtsc

    Typings

    Linting

    TypeScriptFeatures

    TypeScriptClasses

    Interfaces

    Shapes

    TypeInference

    TypeKeyword

    Decorators

    PropertyDecorators

    ClassDecorators

    ParameterDecorators

    2

  • 3.1

    3.1.1

    3.1.2

    3.1.3

    3.1.4

    3.1.5

    3.1.6

    4.1

    4.1.1

    4.1.2

    5.1

    5.1.1

    5.1.2

    5.1.2.1

    5.1.2.2

    5.1.2.3

    5.1.2.4

    5.1.3

    5.1.4

    5.1.5

    6.1

    6.1.1

    6.1.1.1

    6.1.1.2

    6.1.2

    6.1.2.1

    6.1.2.2

    6.1.2.3

    6.1.2.4

    7.1

    7.1.1

    7.1.2

    7.1.3

    7.1.4

    TheJavaScriptToolchain

    SourceControl:git

    TheCommandLine

    CommandLineJavaScript:NodeJS

    Back-EndCodeSharingandDistribution:npm

    ModuleLoading,BundlingandBuildTasks:Webpack

    Chrome

    BootstrappinganAngularApplication

    UnderstandingtheFileStructure

    BootstrappingProviders

    ComponentsinAngular

    CreatingComponents

    ApplicationStructurewithComponents

    PassingDataintoaComponent

    RespondingtoComponentEvents

    UsingTwo-WayDataBinding

    AccessingChildComponentsfromTemplate

    Projection

    StructuringApplicationswithComponents

    UsingOtherComponents

    Directives

    AttributeDirectives

    NgStyleDirective

    NgClassDirective

    StructuralDirectives

    NgIfDirective

    NgForDirective

    NgSwitchDirectives

    UsingMultipleStructuralDirectives

    AdvancedComponents

    ComponentLifecycle

    AccessingOtherComponents

    ViewEncapsulation

    ElementRef

    3

  • 8.1

    8.1.1

    8.1.2

    8.1.3

    8.1.4

    8.1.5

    8.1.6

    8.1.7

    8.1.8

    9.1

    9.1.1

    9.1.2

    9.1.3

    9.1.3.1

    9.1.3.2

    9.1.3.3

    9.1.3.4

    10.1

    10.1.1

    10.1.2

    10.1.2.1

    10.1.2.2

    10.1.2.3

    10.1.3

    10.1.4

    10.1.5

    11.1

    11.1.1

    11.1.2

    11.1.3

    11.1.4

    11.1.5

    11.1.6

    Observables

    UsingObservables

    ErrorHandling

    DisposingSubscriptionsandReleasingResources

    ObservablesvsPromises

    UsingObservablesFromOtherSources

    ObservablesArrayOperations

    ColdvsHotObservables

    Summary

    AngularDependencyInjection

    WhatisDI?

    DIFramework

    Angular'sDI

    @Inject()and@Injectable

    InjectionBeyondClasses

    AvoidingInjectionCollisions:OpaqueToken

    TheInjectorTree

    Http

    MakingRequests

    CatchingRejections

    CatchandRelease

    CancelaRequest

    Retry

    SearchwithflatMap

    EnhancingSearchwithswitchMap

    RequestsasPromises

    ChangeDetection

    ChangeDetectionStrategiesinAngular1vsAngular2

    HowChangeDetectionWorks

    ChangeDetectorClasses

    ChangeDetectionStrategy:OnPush

    EnforcingImmutability

    AdditionalResources

    4

  • 12.1

    13.1

    13.1.1

    13.1.1.1

    13.1.1.1.1

    13.1.1.1.2

    13.1.1.2

    13.1.1.2.1

    13.1.1.2.2

    13.1.2

    13.1.2.1

    13.1.2.2

    14.1

    14.1.1

    14.1.2

    14.1.3

    14.1.3.1

    14.1.3.2

    14.1.4

    14.1.4.1

    14.1.4.1.1

    14.1.4.2

    14.1.4.2.1

    14.1.4.2.2

    14.1.4.3

    14.1.4.4

    14.1.4.5

    15.1

    15.1.1

    15.1.2

    15.1.3

    16.1

    16.1.1

    16.1.2

    Zone.js

    AdvancedAngular

    Directives

    CreatinganAttributeDirective

    ListeningtoanElementHost

    SettingPropertiesinaDirective

    CreatingaStructuralDirective

    ViewContainersandEmbeddedViews

    ProvidingContextVariablestoDirectives

    AoT

    AoTlimitations

    AoTConfiguration

    Immutable.js

    WhatisImmutability?

    TheCaseforImmutability

    JavaScriptSolutions

    Object.assign

    Object.freeze

    Immutable.jsBasics

    Immutable.Map

    Map.merge

    NestedObjects

    DeletingKeys

    MapsareIterable

    Immutable.List

    PerformanceandTransientChanges

    OfficialDocumentation

    Pipes

    UsingPipes

    CustomPipes

    StatefulPipes

    Forms

    GettingStarted

    Template-DrivenForms

    5

  • 16.1.2.1

    16.1.2.2

    16.1.2.3

    16.1.3

    16.1.3.1

    16.1.3.2

    16.1.3.3

    16.1.4

    17.1

    17.1.1

    17.1.2

    17.1.3

    17.1.4

    17.1.5

    17.1.6

    17.1.7

    17.1.8

    18.1

    18.1.1

    18.1.2

    18.1.3

    18.1.4

    18.1.5

    18.1.6

    18.1.7

    18.1.8

    18.1.9

    18.1.10

    19.1

    19.1.1

    19.1.1.1

    19.1.1.2

    19.1.1.3

    NestingFormData

    UsingTemplateModelBinding

    ValidatingTemplate-DrivenForms

    Reactive/Model-DrivenForms

    FormBuilderBasics

    ValidatingFormBuilderForms

    FormBuilderCustomValidation

    VisualCuesforUsers

    Modules

    WhatisanAngularModule?

    AddingComponents,PipesandServicestoaModule

    CreatingaFeatureModule

    DirectiveDuplications

    LazyLoadingaModule

    LazyLoadingandtheDependencyInjectionTree

    SharedModulesandDependencyInjection

    SharingtheSameDependencyInjectionTree

    Routing

    WhyRouting?

    ConfiguringRoutes

    RedirectingtheRoutertoAnotherRoute

    DefiningLinksBetweenRoutes

    DynamicallyAddingRouteComponents

    UsingRouteParameters

    DefiningChildRoutes

    ControllingAccesstoorfromaRoute

    PassingOptionalParameterstoaRoute

    UsingAuxiliaryRoutes

    StateManagement

    Reduxand@ngrx

    Adding@ngrxtoyourProject

    DefiningyourMainApplicationState

    ExampleApplication

    6

  • 19.1.1.4

    19.1.1.5

    19.1.1.6

    19.1.1.7

    19.1.1.8

    19.1.1.9

    19.1.1.10

    19.1.1.11

    19.1.1.12

    19.1.1.13

    19.1.1.14

    20.1

    20.1.1

    20.1.2

    20.1.2.1

    20.1.2.2

    20.1.2.3

    20.1.2.4

    20.1.2.5

    20.1.3

    20.1.4

    20.1.5

    20.1.5.1

    20.1.5.2

    20.1.5.2.1

    20.1.5.3

    20.1.5.4

    20.1.6

    20.1.6.1

    20.1.6.2

    20.1.6.2.1

    20.1.6.2.2

    20.1.6.2.3

    20.1.6.3

    ReadingyourApplicationStateusingSelectors

    Actions

    ModifyingyourApplicationStatebyDispatchingActions

    ReducersandPureFunctions

    ReducersasStateManagement

    CreatingyourApplication'sRootReducer

    ConfiguringyourApplication

    ImplementingComponents

    ComponentArchitecture

    SideEffects

    GettingMoreFromReduxand@ngrx

    TDDTesting

    TheTestingToolchain

    TestSetup

    FilenameConventions

    KarmaConfiguration

    TestBedConfiguration(Optional)

    Typings

    ExecutingTestScripts

    SimpleTest

    UsingChai

    TestingComponents

    VerifyingMethodsandProperties

    InjectingDependenciesandDOMChanges

    OverridingComponentsforTesting

    TestingAsynchronousActions

    RefactoringHard-to-TestCode

    TestingServices

    TestingStrategiesforServices

    TestingHTTPRequests

    UsingMockBackend

    AlternativeMockingStrategy

    TestingJSONPandXHRBack-Ends

    ExecutingTestsAsynchronously

    7

  • 20.1.7

    20.1.7.1

    20.1.7.2

    20.1.7.3

    20.1.7.4

    21.1

    21.1.1

    21.1.1.1

    21.1.1.2

    21.1.1.3

    21.1.2

    21.1.3

    21.1.4

    21.1.4.1

    21.1.4.2

    21.1.5

    21.1.5.1

    21.1.5.2

    21.1.5.3

    21.1.5.4

    21.1.5.5

    21.1.5.6

    21.1.5.7

    21.1.5.8

    22.1

    22.1.1

    22.1.1.1

    22.1.1.2

    22.1.1.3

    22.1.1.4

    22.1.2

    23.1

    23.1.1

    TestingRedux

    TestingSimpleActions

    TestingComplexActions

    TestingReducers

    Afterthoughts

    MigratingAngular1.xProjectstoAngular2

    MigrationPrep

    UpgradingToAngular1.3+Style

    UsingWebpack

    MigratingToTypeScript

    ChoosinganUpgradePath

    AvoidingTotalConversion

    Usingng-metadata(Angular1.xUsing2Style)

    Bootstrappingng-metadata

    ComponentsandServices

    Usingng-upgrade(Angular1.xCoexistingWithAngular2)

    OrderofOperations

    ReplacingServiceswithTypeScriptClasses

    Bootstrappingng-upgrade

    DowngradingComponents

    UpgradingComponents

    ProjectingAngular1ContentintoAngular2Components

    TranscludingAngular2ComponentsintoAngular1Directives

    InjectingAcrossFrameworks

    ProjectSetup

    Webpack

    InstallationandUsage

    Loaders

    Plugins

    Summary

    NPMScriptsIntegration

    AngularCLI

    Setup

    8

  • 23.1.2

    23.1.3

    23.1.4

    23.1.5

    23.1.6

    23.1.7

    23.1.8

    23.1.9

    23.1.10

    23.1.11

    24.1

    24.1.1

    24.1.2

    24.1.2.1

    24.1.2.2

    24.1.2.3

    24.1.3

    24.1.3.1

    24.1.3.2

    24.1.3.3

    24.1.3.4

    24.1.4

    25.1

    25.1.1

    25.1.2

    25.1.3

    25.1.4

    25.1.4.1

    25.1.4.2

    26.1

    26.2

    CreatingaNewApp

    ServingtheApp

    CreatingComponents

    CreatingRoutes

    CreatingOtherThings

    Testing

    Linting

    CLICommandOverview

    AddingThirdPartyLibraries

    IntegratinganExistingApp

    AccessibilityinAngular

    WhyMakemyApplicationAccessible?

    KeyConcernsofAccessibleWebApplications

    SemanticMarkup

    KeyboardAccessibility

    VisualAssistance

    TestingforAccessibility

    IsmyApplicationReadable?

    IsmyApplicationPredictable?

    IsmyApplicationNavigable?

    TestingwithScreenReaders

    AdditionalResources

    InternationalizationinAngular

    Whatistheprocesslikeandhowisinvolved?

    Markingtextinourtemplates

    ExtractingtranslationtextusingtheAngularCLI

    Howtoimportthecompletedtranslationfiles

    UsingtheAoTCompiler

    UsingtheJiTCompiler

    Glossary

    FurtherReadingAndReference

    9

  • 10

  • Rangle'sAngularTrainingBook

    Overthelastthreeandahalfyears,AngularhasbecometheleadingopensourceJavaScriptapplicationframeworkforhundredsofthousandsofprogrammersaroundtheworld.The"1.x"versionofAngularhasbeenwidelyusedandbecameextremelypopularforcomplexapplications.ThenewAngular2.xhasalsoannounceditsfinalreleaseversion.

    AboutRangle’sAngularTrainingBookWedevelopedthisbooktobeusedascoursematerialforRangle'sAngulartraining,butmanypeoplehavefoundittobeusefulforlearningAngularontheirown.ThisbookwillcoverthemostimportantAngulartopics,fromgettingstartedwiththeAngulartoolchaintowritingAngularapplicationsinascalableandmaintainablemanner.

    Ifyoufindthismaterialuseful,youshouldalsoconsiderregisteringforoneofRangle’strainingcourses,whichfacilitatehands-onlearningandareagreatfitforcompaniesthatneedtotransitiontheirtechnologytoAngular,orindividualslookingtoupgradetheirskills.

    Rangle.ioalsohasanAngular1.xbookwhichisgearedtowardswritingAngular1.xapplicationsinanAngular2style.Wehopeyouenjoythisbook.WewelcomeyourfeedbackintheDiscussionArea.

    Introduction

    11

    http://angularjs.blogspot.ca/2016/09/angular2-final.htmlhttp://go.rangle.io/angular-2-traininghttp://go.rangle.io/angular-2-traininghttp://ngcourse-1.rangle.io/https://www.gitbook.com/book/rangle-io/ngcourse2/discussions

  • Introduction

    12

  • LicenseCreativeCommonsAttribution-ShareAlike4.0International(CCBY-SA4.0)

    Thisisahuman-readablesummaryof(andnotasubstitutefor)thelicense.

    Youarefreeto:Share—copyandredistributethematerialinanymediumorformat

    Adapt—remix,transformandbuilduponthematerialforanypurpose,evencommercially.

    Thelicensorcannotrevokethesefreedomsaslongasyoufollowthelicenseterms.

    Underthefollowingterms:Attribution—Youmustgiveappropriatecredit,providealinktothelicense,andindicateifchangesweremade.Youmaydosoinanyreasonablemanner,butnotinanywaythatsuggeststhelicensorendorsesyouoryouruse.

    ShareAlike—Ifyouremix,transformorbuilduponthematerial,youmustdistributeyourcontributionsunderthesamelicenseastheoriginal.

    Noadditionalrestrictions—Youmaynotapplylegaltermsortechnologicalmeasuresthatlegallyrestrictothersfromdoinganythingthelicensepermits.

    License

    13

    https://creativecommons.org/licenses/by-sa/4.0/legalcodehttps://creativecommons.org/licenses/by-sa/4.0/legalcode

  • WhyAngular?Therearemanyfront-endJavaScriptframeworkstochoosefromtoday,eachwithitsownsetoftrade-offs.ManypeoplewerehappywiththefunctionalitythatAngular1.xaffordedthem.Angular2improvedonthatfunctionalityandmadeitfaster,morescalableandmoremodern.OrganizationsthatfoundvalueinAngular1.xwillfindmorevalueinAngular2.

    Angular'sAdvantagesThefirstreleaseofAngularprovidedprogrammerswiththetoolstodevelopandarchitectlargescaleJavaScriptapplications,butitsagehasrevealedanumberofflawsandsharpedges.Angular2wasbuiltonfiveyearsofcommunityfeedback.

    Angular2IsEasier

    ThenewAngularcodebaseismoremodern,morecapableandeasierfornewprogrammerstolearnthanAngular1.x,whilealsobeingeasierforprojectveteranstoworkwith.

    WithAngular1,programmershadtounderstandthedifferencesbetweenControllers,Services,Factories,Providersandotherconceptsthatcouldbeconfusing,especiallyfornewprogrammers.

    Angular2isamorestreamlinedframeworkthatallowsprogrammerstofocusonsimplybuildingJavaScriptclasses.Viewsandcontrollersarereplacedwithcomponents,whichcanbedescribedasarefinedversionofdirectives.EvenexperiencedAngularprogrammersarenotalwaysawareofallthecapabilitiesofAngular1.xdirectives.Angular2componentsareconsiderablyeasiertoread,andtheirAPIfeatureslessjargonthanAngular1.x'sdirectives.Additionally,tohelpeasethetransitiontoAngular2,theAngularteamhasaddeda.componentmethodtoAngular1.5,whichhasbeenback-portedbycommunitymemberToddMottotov1.3.

    TypeScript

    Angular2waswritteninTypeScript,asupersetofJavaScriptthatimplementsmanynewES2016+features.

    Byfocusingonmakingtheframeworkeasierforcomputerstoprocess,Angular2allowsforamuchricherdevelopmentecosystem.Programmersusingsophisticatedtexteditors(orIDEs)willnoticedramaticimprovementswithauto-completionandtypesuggestions.These

    WhyAngular?

    14

    https://toddmotto.com/angular-component-method-back-ported-to-1.3/

  • improvementshelptoreducethecognitiveburdenoflearningAngular2.FortunatelyfortraditionalES5JavaScriptprogrammersthisdoesnotmeanthatdevelopmentmustbedoneinTypeScriptorES2015:programmerscanstillwritevanillaJavaScriptthatrunswithouttranspilation.

    Familiarity

    Despitebeingacompleterewrite,Angular2hasretainedmanyofitscoreconceptsandconventionswithAngular1.x,e.g.astreamlined,"nativeJS"implementationofdependencyinjection.ThismeansthatprogrammerswhoarealreadyproficientwithAngularwillhaveaneasiertimemigratingtoAngular2thananotherlibrarylikeReactorframeworklikeEmber.

    PerformanceandMobile

    Angular2wasdesignedformobilefromthegroundup.Asidefromlimitedprocessingpower,mobiledeviceshaveotherfeaturesandlimitationsthatseparatethemfromtraditionalcomputers.Touchinterfaces,limitedscreenrealestateandmobilehardwarehaveallbeenconsideredinAngular2.

    Desktopcomputerswillalsoseedramaticimprovementsinperformanceandresponsiveness.

    Angular2,likeReactandothermodernframeworks,canleverageperformancegainsbyrenderingHTMLontheserveroreveninawebworker.Dependingonapplication/sitedesignthisisomorphicrenderingcanmakeauser'sexperiencefeelevenmoreinstantaneous.

    Thequestforperformancedoesnotendwithpre-rendering.Angular2makesitselfportabletonativemobilebyintegratingwithNativeScript,anopensourcelibrarythatbridgesJavaScriptandmobile.Additionally,theIonicteamisworkingonanAngular2versionoftheirproduct,providinganotherwaytoleveragenativedevicefeatureswithAngular.

    ProjectArchitectureandMaintenance

    ThefirstiterationofAngularprovidedwebprogrammerswithahighlyflexibleframeworkfordevelopingapplications.Thiswasadramaticshiftformanywebprogrammers,andwhilethatframeworkwashelpful,itbecameevidentthatitwasoftentooflexible.Overtime,bestpracticesevolved,andacommunity-drivenstructurewasendorsed.

    Angular1.xtriedtoworkaroundvariousbrowserlimitationsrelatedtoJavaScript.Thiswasdonebyintroducingamodulesystemthatmadeuseofdependencyinjection.Thissystemwasnovel,butunfortunatelyhadissueswithtooling,notablyminificationandstaticanalysis.

    WhyAngular?

    15

    https://www.nativescript.org/

  • Angular2.xmakesuseoftheES2015modulesystem,andmodernpackagingtoolslikewebpackorSystemJS.Modulesarefarlesscoupledtothe"Angularway",andit'seasiertowritemoregenericJavaScriptandplugitintoAngular.Theremovalofminificationworkaroundsandtheadditionofrigidprescriptionsmakemaintainingexistingapplicationssimpler.Thenewmodulesystemalsomakesiteasiertodevelopeffectivetoolingthatcanreasonbetteraboutlargerprojects.

    NewFeatures

    SomeoftheotherinterestingfeaturesinAngular2are:

    FormBuilderChangeDetectionTemplatingRoutingAnnotationsObservablesShadowDOM

    DifferencesBetweenAngular1&2Notethat"TransitionalArchitecture"referstoastyleofAngular1applicationwritteninawaythatmimicsAngular2'scomponentstyle,butwithcontrollersanddirectivesinsteadofTypeScriptclasses.

    OldSchoolAngular1.x

    Angular1.xBest

    Practices

    TransitionalArchitecture Angular2

    Nestedscopes("$scope",watches)

    Usedheavily Avoided Avoided Gone

    Directivesvscontrollers

    Useasalternatives Usedtogether

    Directivesascomponents

    Componentdirectives

    Controllerandserviceimplementation

    Functions Functions ES6classes ES6classes

    Modulesystem Angular'smodulesAngular'smodules ES6modules

    ES6modules

    Transpilerrequired No No TypeScript TypeScript

    WhyAngular?

    16

  • WhyAngular?

    17

  • EcmaScript6andTypeScriptFeatures

    Figure:ES6andTypeScript

    Thelanguageweusuallycall"JavaScript"isformallyknownas"EcmaScript".ThenewversionofJavaScript,knownas"ES6",offersanumberofnewfeaturesthatextendthepowerofthelanguage.

    ES6isnotwidelysupportedintoday'sbrowsers,soitneedstobetranspiledtoES5.Youcanchoosebetweenseveraltranspilers,butwe'llbeusingTypeScript,whichiswhattheAngularteamusestowriteAngular.AngularmakesuseofanumberoffeaturesofES6andTypeScript.

    EcmaScript6andTypeScriptFeatures

    18

  • ES6JavaScriptwascreatedin1995,butthelanguageisstillthrivingtoday.Therearesubsets,supersets,currentversionsandthelatestversionES6thatbringsalotofnewfeatures.

    Someofthehighlights:

    ClassesArrowFunctionsTemplateStringsInheritanceConstantsandBlockScopedVariablesSpreadandRestoperatorsDestructuringModules

    ES6

    19

  • ClassesClassesareanewfeatureinES6,usedtodescribetheblueprintofanobjectandmakeEcmaScript'sprototypicalinheritancemodelfunctionmorelikeatraditionalclass-basedlanguage.

    classHamburger{constructor(){//Thisistheconstructor.}listToppings(){//Thisisamethod.}}

    Traditionalclass-basedlanguagesoftenreservethewordthistoreferencethecurrent(runtime)instanceoftheclass.InJavascriptthisreferstothecallingcontextandthereforecanchangetobesomethingotherthantheobject.

    ObjectAnobjectisaninstanceofaclasswhichiscreatedusingthenewoperator.Whenusingadotnotationtoaccessamethodontheobject,thiswillrefertotheobjecttotheleftofthedot.

    letburger=newHamburger();burger.listToppings();

    Inthesnippetabove,wheneverthisisusedfrominsideclassHamburger,itwillrefertoobjectburger.

    ChangingCallerContextJavaScriptcodecanoptionallysupplythistoamethodatcalltimeusingoneofthefollowing.

    Function.prototype.call(object[,arg,...])Function.prototype.bind(object[,arg,...])Function.prototype.apply(object[,argsArray])

    Classes

    20

  • Classes

    21

  • ARefresheron thisInsideaJavaScriptclasswe'llbeusingthiskeywordtorefertotheinstanceoftheclass.E.g.,considerthiscase:

    classToppings{...

    formatToppings(){/*implementationdetails*/}

    list(){returnthis.formatToppings(this.toppings);}}

    HerethisreferstoaninstanceoftheToppingsclass.Aslongasthelistmethodiscalledusingdotnotation,likemyToppings.list(),thenthis.formatToppings(this.toppings)invokestheformatToppings()methoddefinedontheinstanceoftheclass.ThiswillalsoensurethatinsideformatToppings,thisreferstothesameinstance.

    However,thiscanalsorefertootherthings.Therearetwobasiccasesthatyoushouldremember.

    1. Methodinvocation:

    someObject.someMethod();

    Here,thisusedinsidesomeMethodwillrefertosomeObject,whichisusuallywhatyouwant.

    2. Functioninvocation:

    someFunction();

    Here,thisusedinsidesomeFunctioncanrefertodifferentthingsdependingonwhetherwearein"strict"modeornot.Withoutusingthe"strict"mode,thisreferstothecontextinwhichsomeFunction()wascalled.Thisisrarelywhatyouwant,anditcanbeconfusingwhenthisisnotwhatyouwereexpecting,becauseofwherethefunctionwascalledfrom.In"strict"mode,thiswouldbeundefined,whichisslightlylessconfusing.

    Refresheron'this'

    22

  • ViewExample

    Oneoftheimplicationsisthatyoucannoteasilydetachamethodfromitsobject.Considerthisexample:

    varlog=console.log;log('Hello');

    Inmanybrowsersthiswillgiveyouanerror.That'sbecauselogexpectsthistorefertoconsole,butthereferencewaslostwhenthefunctionwasdetachedfromconsole.

    Thiscanbefixedbysettingthisexplicitly.Onewaytodothisisbyusingbind()method,whichallowsyoutospecifythevaluetouseforthisinsidetheboundfunction.

    varlog=console.log.bind(console);log('Hello');

    YoucanalsoachievethesameusingFunction.callandFunction.apply,butwewon'tdiscussthishere.

    Anotherinstancewherethiscanbeconfusingiswithrespecttoanonymousfunctions,orfunctionsdeclaredwithinotherfunctions.Considerthefollowing:

    classServerRequest{notify(){...}fetch(){getFromServer(functioncallback(err,data){this.notify();//thisisnotgoingtowork});}}

    Intheabovecasethiswillnotpointtotheexpectedobject:in"strict"modeitwillbeundefined.ThisleadstoanotherES6feature-arrowfunctions,whichwillbecoverednext.

    Refresheron'this'

    23

    http://jsbin.com/vekawimihe/2/edit?js,console

  • ArrowFunctionsES6offerssomenewsyntaxfordealingwiththis:"arrowfunctions".Arrowfunctionsalsomakehigherorderfunctionsmucheasiertoworkwith.

    Thenew"fatarrow"notationcanbeusedtodefineanonymousfunctionsinasimplerway.

    Considerthefollowingexample:

    items.forEach(function(x){console.log(x);incrementedItems.push(x+1);});

    Thiscanberewrittenasan"arrowfunction"usingthefollowingsyntax:

    items.forEach((x)=>{console.log(x);incrementedItems.push(x+1);});

    Functionsthatcalculateasingleexpressionandreturnitsvaluescanbedefinedevensimpler:

    incrementedItems=items.map((x)=>x+1);

    Thelatterisalmostequivalenttothefollowing:

    incrementedItems=items.map(function(x){returnx+1;});

    Thereisoneimportantdifference,however:arrowfunctionsdonotsetalocalcopyofthis,arguments,super,ornew.target.WhenthisisusedinsideanarrowfunctionJavaScriptusesthethisfromtheouterscope.Considerthefollowingexample:

    ArrowFunctions

    24

  • classToppings{constructor(toppings){this.toppings=Array.isArray(toppings)?toppings:[];}outputList(){this.toppings.forEach(function(topping,i){console.log(topping,i+'/'+this.toppings.length);//`this`willbeundefined});}}

    varmyToppings=newToppings(['cheese','lettuce']);

    myToppings.outputList();

    Let'strythiscodeonhttp://jsbin.com.Aswesee,thisgivesusanerror,sincethisisundefinedinsidetheanonymousfunction.

    Now,let'schangethemethodtousethearrowfunction:

    classToppings{constructor(toppings){this.toppings=Array.isArray(toppings)?toppings:[];}outputList(){this.toppings.forEach((topping,i)=>{console.log(topping,i+'/'+this.toppings.length)//`this`works!});}}

    varmyToppings=newToppings(['cheese','lettuce']);

    myToppings.outputList();

    Let'strythiscodeonhttp://jsbin.com.Herethisinsidethearrowfunctionreferstotheinstancevariable.

    Warningarrowfunctionsdonothavetheirownargumentsvariable,whichcanbeconfusingtoveteranJavaScriptprogrammers.superandnew.targetarealsoscopedfromtheouterenclosure.

    ArrowFunctions

    25

    http://jsbin.com/qakigoqulo/edit?js,consolehttp://jsbin.com/tulikutife/edit?js,console

  • TemplateStringsIntraditionalJavaScript,textthatisenclosedwithinmatching"or'marksisconsideredastring.Textwithindoubleorsinglequotescanonlybeononeline.Therewasnowaytoinsertdataintothesestrings.Thisresultedinalotofuglyconcatenationcodethatlookedlike:

    varname='Sam';varage=42;

    console.log('hellomynameis'+name+'Iam'+age+'yearsold');

    ES6introducesanewtypeofstringliteralthatismarkedwithbackticks(`).Thesestringliteralscanincludenewlines,andthereisastringinterpolationforinsertingvariablesintostrings:

    varname='Sam';varage=42;

    console.log(`hellomynameis${name},andIam${age}yearsold`);

    Thereareallsortsofplaceswherethiskindofstringcancomeinhandy,andfront-endwebdevelopmentisoneofthem.

    TemplateStrings

    26

  • InheritanceJavaScript'sinheritanceworksdifferentlyfrominheritanceinotherlanguages,whichcanbeveryconfusing.ES6classesprovideasyntacticsugarattemptingtoalleviatetheissueswithusingprototypicalinheritancepresentinES5.

    Toillustratethis,let'simagewehaveazooapplicationwheretypesofbirdsarecreated.Inclassicalinheritance,wedefineabaseclassandthensubclassittocreateaderivedclass.

    SubclassingTheexamplecodebelowshowshowtoderivePenguinfromBirdusingtheextendskeyword.AlsopayattentiontothesuperkeywordusedinthesubclassconstructorofPenguin,itisusedtopasstheargumenttothebaseclassBird'sconstructor.

    TheBirdclassdefinesthemethodwalkwhichisinheritedbythePenguinclassandisavailableforusebyinstanceofPenguinobjects.LikewisethePenguinclassdefinesthemethodswimwhichisnotavilabletoBirdobjects.Inheritanceworkstop-downfrombaseclasstoitssubclass.

    ObjectInitializationTheclassconstructoriscalledwhenanobjectiscreatedusingthenewoperator,itwillbecalledbeforetheobjectisfullycreated.Aconsturctorisusedtopassinargumentstoinitializethenewlycreatedobject.

    Theorderofobjectcreationstartsfromitsbaseclassandthenmovesdowntoanysubclass(es).

    Inheritance

    27

  • //BaseClass:ES6classBird{constructor(weight,height){this.weight=weight;this.height=height;}

    walk(){console.log('walk!');}}

    //SubclassclassPenguinextendsBird{constructor(weight,height){super(weight,height);}

    swim(){console.log('swim!');}}

    //Penguinobjectletpenguin=newPenguin(...);penguin.walk();//walk!penguin.swim();//swim!

    BelowweshowhowprototypalinheritancewasdonebeforeclasswasintroducedtoJavaScript.

    Inheritance

    28

  • //JavaScriptclassicalinheritance.

    //BirdconstructorfunctionBird(weight,height){this.weight=weight;this.height=height;}

    //AddmethodtoBirdprototype.Bird.prototype.walk=function(){console.log("walk!");};

    //Penguinconstructor.functionPenguin(weight,height){Bird.call(this,weight,height);}

    //Prototypalinheritance(Penguinis-aBird).Penguin.prototype=Object.create(Bird.prototype);Penguin.prototype.constructor=Penguin;

    //AddmethodtoPenguinprototype.Penguin.prototype.swim=function(){console.log("swim!");};

    //CreateaPenguinobject.letpenguin=newPenguin(50,10);

    //CallsmethodonBird,sinceit'snotdefinedbyPenguin.penguin.walk();//walk!

    //CallsmethodonPenguin.penguin.swim();//swim!

    Inheritance

    29

  • DelegationIntheinheritancesectionwelookedatonewaytoextendaclassfunctionality,thereissecondwayusingdelegationtoextendfunctionality.Withdelegation,oneobjectwillcontainareferencetoadifferentobjectthatitwillhandoffarequesttoperformthefunctionality.

    ThecodebelowshowshowtousedelegationwiththeBirdclassandPenguinclass.ThePenguinclasshasareferencetotheBirdclassanditdelegatesthecallmadetoit'swalkmethodovertoBird'swalkmethod.

    //ES6classBird{constructor(weight,height){this.weight=weight;this.height=height;}walk(){console.log('walk!');}}

    classPenguin{constructor(bird){this.bird=bird;}walk(){this.bird.walk();}swim(){console.log('swim!');}}

    constbird=newBird(...);constpenguin=newPenguin(bird);penguin.walk();//walk!penguin.swim();//swim!

    Agooddiscussionon'behaviourdelegation'canbefoundhere.

    Delegation

    30

    https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch6.md

  • ConstantsandBlockScopedVariablesES6introducestheconceptofblockscoping.BlockscopingwillbefamiliartoprogrammersfromotherlanguageslikeC,Java,orevenPHP.InES5JavaScriptandearlier,varsarescopedtofunctions,andtheycan"see"outsidetheirfunctionstotheoutercontext.

    varfive=5;varthreeAlso=three;//error

    functionscope1(){varthree=3;varfiveAlso=five;//==5varsevenAlso=seven;//error}

    functionscope2(){varseven=7;varfiveAlso=five;//==5varthreeAlso=three;//error}

    InES5functionswereessentiallycontainersthatcouldbe"seen"outof,butnotinto.

    InES6varstillworksthatway,usingfunctionsascontainers,buttherearetwonewwaystodeclarevariables:constandlet.

    constandletuse{and}blocksascontainers,hence"blockscope".Blockscopingismostusefulduringloops.Considerthefollowing:

    vari;for(i=0;i<10;i+=1){varj=i;letk=i;}console.log(j);//9console.log(k);//undefined

    Despitetheintroductionofblockscoping,functionsarestillthepreferredmechanismfordealingwithmostloops.

    letworkslikevarinthesensethatitsdataisread/write.letisalsousefulwhenusedinaforloop.Forexample,withoutlet,thefollowingexamplewouldoutput5,5,5,5,5:

    ConstantsandBlockScopedVariables

    31

  • for(varx=0;xconsole.log(x),0)}

    However,whenusingletinsteadofvar,thevaluewouldbescopedinawaythatpeoplewouldexpect.

    for(letx=0;xconsole.log(x),0)}

    Alternatively,constisread-only.Onceconsthasbeenassigned,theidentifiercannotbereassigned.

    Forexample:

    constmyName='pat';letyourName='jo';

    yourName='sam';//assignsmyName='jan';//error

    Theread-onlynaturecanbedemonstratedwithanyobject:

    constliteral={};

    literal.attribute='test';//fineliteral=[];//error;

    Howevertherearetwocaseswhereconstdoesnotworkasyouthinkitshould.

    1. Aconstobjectliteral.2. Aconstreferencetoanobject.

    ConstObjectLiteral

    constperson={name:'Tammy'};

    person.name='Pushpa';//OK,namepropertychanged.

    person=null;//"TypeError:Assignmenttoconstantvariable.

    ConstantsandBlockScopedVariables

    32

  • Theexampleabovedemonstratesthatweareabletochangethenamepropertyofobjectperson,butweareunabletoresetthereferencepersonsinceithasbeenmarkedasconst.

    ConstReferenceToAnObjectSomethingsimilartotheabovecodeisusingaconstreference,belowwe'veswitchtousingletfortheliteralobject.

    letperson={name:'Tammy'};

    constp=person;

    p.name='Pushpa';//OK,namepropertychanged.

    p=null;//"TypeError:Assignmenttoconstantvariable.

    Takeaway,markinganobjectreferenceconstdoesnotmakepropertiesinsidetheobjectconst.

    Ref:.

    ConstantsandBlockScopedVariables

    33

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

  • SpreadSyntax(SpreadElement)andRestparametersASpreadsyntaxallowsin-placeexpansionofanexpressionforthefollowingcases:

    1. Array2. Functioncall3. Multiplevariabledestructuring

    Restparametersworksintheoppositedirectionofthespreadsyntax,itcollectsanindefinitenumberofcommaseparatedexpressionsintoanarray.

    SpreadSyntaxSpreadexample:

    constadd=(a,b)=>a+b;letargs=[3,5];add(...args);//sameas`add(args[0],args[1])`,or`add.apply(null,args)`

    Functionsaren'ttheonlyplaceinJavaScriptthatmakesuseofcommaseparatedlists-arrayscannowbeconcatenatedwithease:

    letcde=['c','d','e'];letscale=['a','b',...cde,'f','g'];//['a','b','c','d','e','f','g']

    Similarly,objectliteralscandothesamething:

    letmapABC={a:5,b:6,c:3};letmapABCD={...mapABC,d:7};//{a:5,b:6,c:3,d:7}

    RestparameterRestparameterssharetheellipsislikesyntaxofspreadsyntaxbutareusedforadifferentpurpose.Restparametersareusedtoaccessindefinitenumberofargumentspassedtoafunction.Forexample:

    ...spreadand...rest

    34

  • functionaddSimple(a,b){returna+b;}

    functionadd(...numbers){returnnumbers[0]+numbers[1];}

    addSimple(3,2);//5add(3,2);//5

    //orines6style:constaddEs6=(...numbers)=>numbers.reduce((p,c)=>p+c,0);

    addEs6(1,2,3);//6

    TechnicallyJavaScriptalreadyhadanargumentsvariablesetoneachfunction(exceptforarrowfunctions),howeverargumentshasalotofissues,oneofwhichisthefactthatitisnottechnicallyanarray.

    Restparametersareinfactarrayswhichprovidesaccesstomethodslikemap,filter,reduceandmore.Theotherimportantdifferenceisthatrestparametersonlyincludeargumentsnotspecificallynamedinafunctionlikeso:

    functionprint(a,b,c,...more){console.log(more[0]);console.log(arguments[0]);}

    print(1,2,3,4,5);//4//1

    Note:CommonlyspreadsyntaxandrestparametersarereferencedasSpreadandRestoperatorsbuttheyaren'toperatorsaccordingtoECMAScriptspecifications.FewreferencesMDN-SpreadSyntax,MDN-RestParameters,ECMAScriptSpec-SpreadSyntax,ECMAScriptSpec-RestParameters

    ...spreadand...rest

    35

    https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Spread_operatorhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parametershttp://www.ecma-international.org/ecma-262/6.0/#sec-array-initializerhttp://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions

  • DestructuringDestructuringisawaytoquicklyextractdataoutofan{}or[]withouthavingtowritemuchcode.

    ToborrowfromtheMDN,destructuringcanbeusedtoturnthefollowing:

    letfoo=['one','two','three'];

    letone=foo[0];lettwo=foo[1];letthree=foo[2];

    into

    letfoo=['one','two','three'];let[one,two,three]=foo;console.log(one);//'one'

    Thisisprettyinteresting,butatfirstitmightbehardtoseetheusecase.ES6alsosupportsobjectdestructuring,whichmightmakeusesmoreobvious:

    letmyModule={drawSquare:functiondrawSquare(length){/*implementation*/},drawCircle:functiondrawCircle(radius){/*implementation*/},drawText:functiondrawText(text){/*implementation*/},};

    let{drawSquare,drawText}=myModule;

    drawSquare(5);drawText('hello');

    Destructuringcanalsobeusedforpassingobjectsintoafunction,allowingyoutopullspecificpropertiesoutofanobjectinaconcisemanner.Itisalsopossibletoassigndefaultvaluestodestructuredarguments,whichcanbeausefulpatternifpassinginaconfigurationobject.

    Destructuring

    36

    https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

  • letjane={firstName:'Jane',lastName:'Doe'};letjohn={firstName:'John',lastName:'Doe',middleName:'Smith'}functionsayName({firstName,lastName,middleName='N/A'}){console.log(`Hello${firstName}${middleName}${lastName}`)}

    sayName(jane)//->HelloJaneN/ADoesayName(john)//->HeloJohnSmithDoe

    Therearemanymoresophisticatedthingsthatcanbedonewithdestructuring,andtheMDNhassomegreatexamples,includingnestedobjectdestructuringanddynamicdestructuringwithfor...inoperators".

    Destructuring

    37

    https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

  • ES6ModulesES6introducedmodulesupport.AmoduleinES6issinglefilethatallowscodeanddatatobeisolated,ithelpsinorganizingandgroupingcodelogically.Inotherlanguagesit'scalledapackageorlibrary.

    Allcodeanddatainsidethemodulehasfilescope,whatthismeansistheyarenotaccessiblefromcodeoutsidethemodule.Tosharecodeordataoutsideamodule,itneedstobeexportedusingtheexportkeyword.

    //File:circle.js

    exportconstpi=3.141592;

    exportconstcircumference=diameter=>diameter*pi;

    ThecodeaboveusestheArrowfunctionforcircumference.Readmoreaboutarrowfunctionshere

    ModuleSystemsUsingamoduleonthebackend(serverside)isrelativelystraightforward,yousimplymakeuseoftheimportkeyword.HoweverWebBrowsershavenoconceptofmodulesorimport,theyjustknowhowtoloadjavascriptcode.Weneedawaytobringinajavascriptmoduletostartusingitfromotherjavascriptcode.Thisiswhereamoduleloadercomesin.

    Wewon'tgetintothevariousmodulesystemsoutthere,butit'sworthunderstandingtherearevariousmoduleloadersavailable.Thepopularchoicesoutthereare:

    RequireJSSystemJSWebpack

    LoadingaModuleFromaBrowserBelowwemakeuseofSystemJStoloadamodule.ThescriptfirstloadsthecodefortheSystemJSlibrary,thenthefunctioncallSystem.importisusetoimport(load)theappmodule.

    Modules

    38

    https://angular-2-training-book.rangle.io/handout/features/arrow_functions.html

  • LoadingES6modulesisalittletrickier.InanES6-compliantbrowseryouusetheSystemkeywordtoloadmodulesasynchronously.Tomakeourcodeworkwithcurrentbrowsers,however,wewillusetheSystemJSlibraryasapolyfill:

    varpromise=System.import('app').then(function(){console.log('Loaded!');}).then(null,function(error){console.error('Failedtoload:',error);});

    Modules

    39

  • TypeScriptES6isthecurrentversionofJavaScript.TypeScriptisasupersetofES6,whichmeansallES6featuresarepartofTypeScript,butnotallTypeScriptfeaturesarepartofES6.Consequently,TypeScriptmustbetranspiledintoES5toruninmostbrowsers.

    OneofTypeScript'sprimaryfeaturesistheadditionoftypeinformation,hencethename.ThistypeinformationcanhelpmakeJavaScriptprogramsmorepredictableandeasiertoreasonabout.

    Typesletdeveloperswritemoreexplicit"contracts".Inotherwords,thingslikefunctionsignaturesaremoreexplicit.

    WithoutTS:

    functionadd(a,b){returna+b;}

    add(1,3);//4add(1,'3');//'13'

    WithTS:

    functionadd(a:number,b:number){returna+b;}

    add(1,3);//4//compilererrorbeforeJSisevenproducedadd(1,'3');//'13'

    TypeScript

    40

  • GettingStartedWithTypeScriptInstalltheTypeScripttranspilerusingnpm:

    $npminstall-gtypescript

    ThenusetsctomanuallycompileaTypeScriptsourcefileintoES5:

    $tsctest.ts$nodetest.js

    NoteAboutES6Examples

    OurearlierES6classwon'tcompilenow.TypeScriptismoredemandingthanES6anditexpectsinstancepropertiestobedeclared:

    classPizza{toppings:string[];constructor(toppings:string[]){this.toppings=toppings;}}

    Notethatnowthatwe'vedeclaredtoppingstobeanarrayofstrings,TypeScriptwillenforcethis.Ifwetrytoassignanumbertoit,wewillgetanerroratcompilationtime.

    Ifyouwanttohaveapropertythatcanbesettoavalueofanytype,however,youcanstilldothis:justdeclareitstypetobe"any":

    classPizza{toppings:any;//...}

    GettingStartedWithTypeScript

    41

  • WorkingWith tscSofartschasbeenusedtocompileasinglefile.Typicallyprogrammershavealotmorethanonefiletocompile.Thankfullytsccanhandlemultiplefilesasarguments.

    Imaginetwoultrasimplefiles/modules:

    a.ts

    exportconstA=(a)=>console.log(a);

    b.ts

    exportconstB=(b)=>console.log(b);

    [email protected]:

    $tsc./a.ts./b.tsa.ts(1,1):errorTS1148:Cannotcompilemodulesunlessthe'--module'flagisprovided.

    Hmmm.What'sthedealwiththismoduleflag?TypeScripthasahelpmenu,let'stakealook:

    $tsc--help|grepmodule-mKIND,--moduleKINDSpecifymodulecodegeneration:'commonjs','amd','system','umd'or'es2015'--moduleResolutionSpecifiesmoduleresolutionstrategy:'node'(Node.js)or'classic'(TypeScriptpre-1.6).

    (TypeScripthasmorehelpthanwhatwe'veshown;wefilteredbygrepforbrevity.)Therearetwohelpentriesthatreference"module",and--moduleistheoneTypeScriptwascomplainingabout.ThedescriptionexplainsthatTypeScriptsupportsanumberofdifferentmoduleschemes.Forthemomentcommonjsisdesirable.Thiswillproducemodulesthatarecompatiblewithnode.js'smodulesystem.

    $tsc-mcommonjs./a.ts./b.ts

    [email protected],tschasadefaultrulefor--moduleoption:target==='ES6'?'ES6':'commonjs'(moredetailscanbefoundhere),sowecansimplyrun:

    WorkingWithtsc

    42

    https://www.typescriptlang.org/docs/handbook/compiler-options.html

  • $tsc./a.ts./b.ts

    tscshouldproducenooutput.Inmanycommandlinetraditions,nooutputisactuallyamarkofsuccess.ListingthedirectorycontentswillconfirmthatourTypeScriptfilesdidinfactcompile.

    $lsa.jsa.tsb.jsb.ts

    Excellent-therearenowtwoJavaScriptmodulesreadyforconsumption.

    Tellingthetsccommandwhattocompilebecomestediousandlaborintensiveevenonsmallprojects.FortunatelyTypeScripthasameansofsimplifyingthis.tsconfig.jsonfilesletprogrammerswritedownallthecompilersettingstheywant.Whentscisrun,itlooksfortsconfig.jsonfilesandusestheirrulestocompileJavaScript.

    ForAngularprojectsthereareanumberofspecificsettingsthatneedtobeconfiguredinaproject'stsconfig.json

    {"compilerOptions":{"module":"commonjs","target":"es5","emitDecoratorMetadata":true,"experimentalDecorators":true,"noImplicitAny":false,"removeComments":false,"sourceMap":true},"exclude":["node_modules","dist/"]}

    Target

    Thecompilationtarget.TypeScriptsupportstargetingdifferentplatformsdependingonyourneeds.Inourcase,we'retargetingmodernbrowserswhichsupportES5.

    Module

    WorkingWithtsc

    43

  • Thetargetmoduleresolutioninterface.We'reintegratingTypeScriptthroughwebpackwhichsupportsdifferentinterfaces.We'vedecidedtousenode'smoduleresolutioninterface,commonjs.

    Decorators

    DecoratorsupportinTypeScripthasn'tbeenfinalizedyetbutsinceAngularusesdecoratorsextensively,theseneedtobesettotrue.Decoratorshavenotbeenintroducedyet,andwillbecoveredlaterinthissection.

    TypeScriptwithWebpack

    Wewon'tberunningtscmanually,however.Instead,webpack'sts-loaderwilldothetranspilationduringthebuild:

    //webpack.config.js//...rules:[{test:/\.ts$/,loader:'ts',exclude:/node_modules/},//...]

    Thisloadercallstscforus,anditwilluseourtsconfig.json.

    WorkingWithtsc

    44

    http://rbuckton.github.io/ReflectDecorators/typescript.html

  • TypingsAstutereadersmightbewonderingwhathappenswhenTypeScriptprogrammersneedtointerfacewithJavaScriptmodulesthathavenotypeinformation.TypeScriptrecognizesfileslabelled*.d.tsasdefinitionfiles.ThesefilesaremeanttouseTypeScripttodescribeinterfacespresentedbyJavaScriptlibraries.

    TherearecommunitiesofpeoplededicatedtocreatingtypingsforJavaScriptprojects.Thereisalsoautilitycalledtypings(npminstall--save-devtypings)thatcanbeusedtomanagethirdpartytypingsfromavarietyofsources.(DeprecatedinTypeScript2.0)

    InTypeScript2.0,userscangettypefilesdirectlyfrom@typesthroughnpm(forexample,npminstall--save@types/lodashwillinstalllodashtypefile).

    Typings

    45

  • LintingManyeditorssupporttheconceptof"linting"-agrammarcheckforcomputerprograms.Lintingcanbedoneinaprogrammer'seditorand/orthroughautomation.

    ForTypeScriptthereisapackagecalledtslint,(npminstall--save-devtslint)whichcanbepluggedintomanyeditors.tslintcanalsobeconfiguredwithatslint.jsonfile.

    Webpackcanruntslintbeforeitattemptstoruntsc.Thisisdonebyinstallingtslint-loader(npminstall--save-devtslint-loader)whichplugsintowebpacklikeso:

    //...module:{preLoaders:[{test:/\.ts$/,loader:'tslint'}],loaders:[{test:/\.ts$/,loader:'ts',exclude:/node_modules/},//...]//...}

    Linting

    46

  • TypeScriptFeaturesNowthatproducingJavaScriptfromTypeScriptcodehasbeende-mystified,someofitsfeaturescanbedescribedandexperimentedwith.

    TypesInterfacesShapesDecorators

    TypesManypeopledonotrealizeit,butJavaScriptdoesinfacthavetypes,they'rejust"ducktyped",whichroughlymeansthattheprogrammerdoesnothavetothinkaboutthem.JavaScript'stypesalsoexistinTypeScript:

    boolean(true/false)numberintegers,floats,InfinityandNaNstringcharactersandstringsofcharacters[]Arraysofothertypes,likenumber[]orboolean[]{}Objectliteralundefinednotset

    TypeScriptalsoadds

    enumenumerationslike{Red,Blue,Green}anyuseanytypevoidnothing

    Primitivetypeexample:

    TypeScriptFeatures

    47

  • letisDone:boolean=false;letheight:number=6;letname:string="bob";letlist:number[]=[1,2,3];letlist:Array=[1,2,3];enumColor{Red,Green,Blue};letc:Color=Color.Green;letnotSure:any=4;notSure="maybeastringinstead";notSure=false;//okay,definitelyaboolean

    functionshowMessage(data:string):void{alert(data);}showMessage('hello');

    ThisillustratestheprimitivetypesinTypeScript,andendsbyillustratingashowMessagefunction.Inthisfunctiontheparametershavespecifictypesthatarecheckedwhentscisrun.

    InmanyJavaScriptfunctionsit'squitecommonforfunctionstotakeoptionalparameters.TypeScriptprovidessupportforthis,likeso:

    functionlogMessage(message:string,isDebug?:boolean){if(isDebug){console.log('Debug:'+message);}else{console.log(message);}}logMessage('hi');//'hi'logMessage('test',true);//'Debug:test'

    Usinga?letstscknowthatisDebugisanoptionalparameter.tscwillnotcomplainifisDebugisomitted.

    TypeScriptFeatures

    48

  • TypeScriptClassesTypeScriptalsotreatsclassesastheirowntype:

    classFoo{foo:number;}classBar{bar:string;}

    classBaz{constructor(foo:Foo,bar:Bar){}}

    letbaz=newBaz(newFoo(),newBar());//validbaz=newBaz(newBar(),newFoo());//tscerrors

    Likefunctionparameters,classessometimeshaveoptionalmembers.Thesame?:syntaxcanbeusedonaclassdefinition:

    classPerson{name:string;nickName?:string;}

    Intheaboveexample,aninstanceofPersonisguaranteedtohaveaname,andmightoptionallyhaveanickName

    TypeScriptClasses

    49

  • InterfacesAninterfaceisaTypeScriptartifact,itisnotpartofECMAScript.Aninterfaceisawaytodefineacontractonafunctionwithrespecttotheargumentsandtheirtype.Alongwithfunctions,aninterfacecanalsobeusedwithaClassaswelltodefinecustomtypes.

    Aninterfaceisanabstracttype,itdoesnotcontainanycodeasaclassdoes.Itonlydefinesthe'signature'orshapeofanAPI.Duringtranspilation,aninterfacewillnotgenerateanycode,itisonlyusedbyTypescriptfortypecheckingduringdevelopment.

    HereisanexampleofaninterfacedescribingafunctionAPI:

    interfaceCallback{(error:Error,data:any):void;}

    functioncallServer(callback:Callback){callback(null,'hi');}

    callServer((error,data)=>console.log(data));//'hi'callServer('hi');//tscerror

    SometimesJavaScriptfunctionscanacceptmultipletypesaswellasvaryingarguments,thatis,theycanhavedifferentcallsignatures.Interfacescanbeusedtospecifythis.

    interfacePrintOutput{(message:string):void;//commoncase(message:string[]):void;//lesscommoncase}

    letprintOut:PrintOutput=(message)=>{if(Array.isArray(message)){console.log(message.join(','));}else{console.log(message);}}

    printOut('hello');//'hello'printOut(['hi','bye']);//'hi,bye'

    Hereisanexampleofaninterfacedescribinganobjectliteral:

    Interfaces

    50

  • interfaceAction{type:string;}

    leta:Action={type:'literal'}

    Interfaces

    51

  • ShapesUnderneathTypeScriptisJavaScript,andunderneathJavaScriptistypicallyaJIT(Just-In-Timecompiler).GivenJavaScript'sunderlyingsemantics,typesaretypicallyreasonedaboutby"shapes".TheseunderlyingshapesworklikeTypeScript'sinterfaces,andareinfacthowTypeScriptcomparescustomtypeslikeclassesandinterfaces.

    Consideranexpansionofthepreviousexample:

    interfaceAction{type:string;}

    leta:Action={type:'literal'}

    classNotAnAction{type:string;constructor(){this.type='Constructorfunction(class)';}}

    a=newNotAnAction();//validTypeScript!

    DespitethefactthatActionandNotAnActionhavedifferentidentifiers,tscletsusassignaninstanceofNotAnActiontoawhichhasatypeofAction.ThisisbecauseTypeScriptonlyreallycaresthatobjectshavethesameshape.Inotherwordsiftwoobjectshavethesameattributes,withthesametypings,thosetwoobjectsareconsideredtobeofthesametype.

    Shapes

    52

  • TypeInferenceOnecommonmisconceptionaboutTypeScript'stypesisthatcodeneedstoexplicitlydescribetypesateverypossibleopportunity.Fortunatelythisisnotthecase.TypeScripthasarichtypeinferencesystemthatwill"fillintheblanks"fortheprogrammer.Considerthefollowing:

    type-inference-finds-error.ts

    letnumbers=[2,3,5,7,11];numbers=['thiswillgenerateatypeerror'];

    tsc./type-inference-finds-error.tstype-inference-finds-error.ts(2,1):errorTS2322:Type'string[]'isnotassignabletotype'number[]'.Type'string'isnotassignabletotype'number'.

    Thecodecontainsnoextratypeinformation.Infact,it'svalidES6.Ifvarhadbeenused,itwouldbevalidES5.YetTypeScriptisstillabletodeterminetypeinformation.

    Typeinferencecanalsoworkthroughcontext,whichishandywithcallbacks.Considerthefollowing:

    type-inference-finds-error-2.ts

    interfaceFakeEvent{type:string;}

    interfaceFakeEventHandler{(e:FakeEvent):void;}

    classFakeWindow{onMouseDown:FakeEventHandler}constfakeWindow=newFakeWindow();

    fakeWindow.onMouseDown=(a:number)=>{//thiswillfail};

    TypeInference

    53

  • tsc./type-inference-finds-error-2.tstype-inference-finds-error-2.ts(14,1):errorTS2322:Type'(a:number)=>void'isnotassignabletotype'FakeEventHandler'.Typesofparameters'a'and'e'areincompatible.Type'number'isnotassignabletotype'FakeEvent'.Property'type'ismissingintype'Number'.

    Inthisexamplethecontextisnotobvioussincetheinterfaceshavebeendefinedexplicitly.Inabrowserenvironmentwitharealwindowobject,thiswouldbeahandyfeature,especiallythetypecompletionoftheEventobject.

    TypeInference

    54

  • TypeKeywordThetypekeyworddefinesanaliastoatype.

    typestr=string;letcheese:str='gorgonzola';letcake:str=10;//Type'number'isnotassignabletotype'string'

    Atfirstglance,thisdoesnotappeartobeveryuseful(eventheerrormentionstheoriginaltype),butastypeannotationsbecomemorecomplex,thebenefitsofthetypekeywordbecomeapparent.

    UnionTypes

    Uniontypesallowtypeannotationstospecifythatapropertyshouldbeoneofasetoftypes(either/or).

    functionadmitAge(age:number|string):string{return`Iam${age},alright?!`;}

    admitAge(30);//'Iam30,alright?!'admitAge('Forty');//'IamForty,alright?!'

    Thetypekeywordsimplifiesannotatingandreusinguniontypes.

    typeAge=number|string;

    functionadmitAge(age:Age):string{return`Iam${age},alright?!`;}

    letmyAge:Age=50;letyourAge:Age='OneHundred';admitAge(yourAge);//'IamOneHundred,alright?!'

    Auniontypeofstringliteraltypesisaveryusefulpattern,creatingwhatisbasicallyanenumwithstringvalues.

    TypeKeyword

    55

  • typePartyZone="pizzahut"|"waterpark"|"bowlingalley"|"abandonedwarehouse";

    functiongoToParty(place:PartyZone):string{return`letsgotothe${place}`;}

    goToParty("pizzahut");goToParty("chucke.cheese");//Argumentoftype`"chucke.cheese"'isnotassignabletoparameteroftype'PartyZone'

    IntersectionTypes

    Intersectiontypesarethecombinationoftwoormoretypes.Usefulforobjectsandparamsthatneedtoimplementmorethanoneinterface.

    interfaceKicker{kick(speed:number):number;}

    interfacePuncher{punch(power:number):number;}//assignintersectiontypedefinitiontoaliasKickPunchertypeKickPuncher=Kicker&Puncher;

    functionattack(warrior:KickPuncher){warrior.kick(102);warrior.punch(412);warrior.judoChop();//Property'judoChop'doesnotexistontype'KickPuncher'}

    FunctionTypeDefinitions

    Functiontypeannotationscangetmuchmorespecificthantypescriptsbuilt-inFunctiontype.Functiontypedefinitionsallowyoutoattachafunctionsignaturetoit'sowntype.

    typeMaybeError=Error|null;typeCallback=(err:MaybeError,response:Object)=>void;

    functionsendRequest(cb:Callback):void{if(cb){cb(null,{});}}

    ThesyntaxissimilartoES6fat-arrowfunctions.([params])=>[returntype].

    TypeKeyword

    56

  • Toillustratethehowmuchthetypekeywordimprovedthereadabilityoftheprevioussnippet,hereisthefunctiontypedefinedinline.

    functionsendRequest(cb:(err:Error|null,response:Object)=>void):void{if(cb){cb(null,{});}}

    TypeKeyword

    57

  • DecoratorsDecoratorsareproposedforafutureversionofJavaScript,buttheAngularteamreallywantedtousethem,andtheyhavebeenincludedinTypeScript.

    Decoratorsarefunctionsthatareinvokedwithaprefixed@symbol,andimmediatelyfollowedbyaclass,parameter,methodorproperty.Thedecoratorfunctionissuppliedinformationabouttheclass,parameterormethod,andthedecoratorfunctionreturnssomethinginitsplace,ormanipulatesitstargetinsomeway.Typicallythe"something"adecoratorreturnsisthesamethingthatwaspassedin,butithasbeenaugmentedinsomeway.

    DecoratorsarequitenewinTypeScript,andmostusecasesdemonstratetheuseofexistingdecorators.However,decoratorsarejustfunctions,andareeasiertoreasonaboutafterwalkingthroughafewexamples.

    Decoratorsarefunctions,andtherearefourthings(class,parameter,methodandproperty)thatcanbedecorated;consequentlytherearefourdifferentfunctionsignaturesfordecorators:

    class:declaretypeClassDecorator=(target:TFunction)=>TFunction|void;

    property:declaretypePropertyDecorator=(target:Object,propertyKey:string|symbol)=>void;

    method:declaretypeMethodDecorator=(target:Object,propertyKey:string|symbol,descriptor:TypedPropertyDescriptor)=>TypedPropertyDescriptor|void;

    parameter:declaretypeParameterDecorator=(target:Object,propertyKey:string|symbol,parameterIndex:number)=>void;

    ReaderswhohaveplayedwithAngularwillnoticethatthesesignaturesdonotlooklikethesignaturesusedbyAngularspecificdecoratorslike@Component().

    Noticethe()[email protected]@ComponentiscalledonceJavaScriptencounters@Component().Inturn,thismeansthattheremustbeaComponentfunctionsomewherethatreturnsafunctionmatchingoneofthedecoratorsignaturesoutlinedabove.Thisisanexampleofthedecoratorfactorypattern.

    Ifdecoratorsstilllookconfusing,perhapssomeexampleswillclearthingsup.

    Decorators

    58

  • PropertyDecoratorsPropertydecoratorsworkwithpropertiesofclasses.

    functionOverride(label:string){returnfunction(target:any,key:string){Object.defineProperty(target,key,{configurable:false,get:()=>label});}}

    classTest{@Override('test')//invokesOverride,whichreturnsthedecoratorname:string='pat';}

    lett=newTest();console.log(t.name);//'test'

    Theaboveexamplemustbecompiledwithboththe--experimentalDecoratorsand--emitDecoratorMetadataflags.

    Inthiscasethedecoratedpropertyisreplacedbythelabelpassedtothedecorator.It'simportanttonotethatpropertyvaluescannotbedirectlymanipulatedbythedecorator;insteadanaccessorisused.

    Here'saclassicpropertyexamplethatusesaplaindecorator

    functionReadOnly(target:any,key:string){Object.defineProperty(target,key,{writable:false});}

    classTest{@ReadOnly//noticethereareno`()`name:string;}

    constt=newTest();t.name='jan';console.log(t.name);//'undefined'

    Inthiscasethenamepropertyisnotwritable,andremainsundefined.

    PropertyDecorators

    59

  • PropertyDecorators

    60

  • ClassDecorators

    functionlog(prefix?:string){return(target)=>{//saveareferencetotheoriginalconstructorvaroriginal=target;

    //autilityfunctiontogenerateinstancesofaclassfunctionconstruct(constructor,args){varc:any=function(){returnconstructor.apply(this,args);}c.prototype=constructor.prototype;returnnewc();}

    //thenewconstructorbehaviorvarf:any=function(...args){console.log(prefix+original.name);returnconstruct(original,args);}

    //copyprototypesoinstanceofoperatorstillworksf.prototype=original.prototype;

    //returnnewconstructor(willoverrideoriginal)returnf;};}

    @log('hello')classWorld{}

    constw=newWorld();//outputs"helloWorld"

    Intheexamplelogisinvokedusing@,andpassedastringasaparameter,@log()returnsananonymousfunctionthatistheactualdecorator.

    Thedecoratorfunctiontakesaclass,orconstructorfunction(ES5)asanargument.ThedecoratorfunctionthenreturnsanewclassconstructionfunctionthatisusedwheneverWorldisinstantiated.

    Thisdecoratordoesnothingotherthanlogoutitsgivenparameter,anditstarget'sclassnametotheconsole.

    ClassDecorators

    61

  • ClassDecorators

    62

  • ParameterDecorators

    functionlogPosition(target:any,propertyKey:string,parameterIndex:number){console.log(parameterIndex);}

    classCow{say(b:string,@logPositionc:boolean){console.log(b);}}

    newCow().say('hello',false);//outputs1(newline)hello

    Theabovedemonstratesdecoratingmethodparameters.ReadersfamiliarwithAngularcannowimaginehowAngularimplementedtheir@Inject()system.

    ParameterDecorators

    63

  • TheJavaScriptToolchainInthissection,we'lldescribethetoolsthatyou'llbeusingfortherestofthecourse.

    Figure:HandToolsbyM338islicensedunderPublicDomain(http://commons.wikimedia.org/wiki/File:Hand_tools.jpg)

    TheJavaScriptToolchain

    64

  • SourceControl:GitAsourcecontrol,sometimescalledaversioncontrolbringschangemanagementtosavingfilesatdifferentpointsinthedevelopmentprocess.AVersioncontrolsystem(VCS)thatwillwemakeuseofisGit.

    Gitisadecentralizeddistributedversioningsystem,itallowsprogrammerstocollaborateonthesamecodebasewithoutsteppingoneachother'stoes.Ithasbecomethede-factosourcecontrolsystemforopensourcedevelopmentbecauseofitsdecentralizedmodelandcheapbranchingfeatures.

    FormoreinformationonhowtouseGit,headovertoProGit

    SourceControl:git

    65

    http://git-scm.com/https://www.gitbook.com/book/gitbookio/progit/details

  • TheCommandLineJavaScriptdevelopmenttoolsareverycommandlineoriented.IfyoucomefromaWindowsbackgroundyoumayfindthisunfamiliar.Howeverthecommandlineprovidesbettersupportforautomatingdevelopmenttasks,soit'sworthgettingcomfortablewithit.

    Wewillprovideexamplesforallcommandlineactivitiesrequiredbythiscourse.

    TheCommandLine

    66

  • CommandLineJavaScript:NodeJSNode.jsisaJavaScriptruntimeenvironmentthatallowsJavaScriptcodetorunoutsideofabrowserusingGoogleV8JavaScriptengine.Node.jsisusedforwrittingfastexecutingcodeontheservertohandleeventsandnon-blockingI/Oefficently.

    REPL(Read-Eval-Print-Loop)toquicklywriteandtestJavaScriptcode.TheV8JavaScriptinterpreter.ModulesfordoingOStaskslikefileI/O,HTTP,etc.

    WhileNode.jswasinitiallyintendedforwritingservercodeinJavaScript,todayitiswidelyusedbyJavaScripttools,whichmakesitrelevanttofront-endprogrammerstoo.Alotofthetoolsyou'llbeusinginthiscourseleverageNode.js.

    CommandLineJavaScript:NodeJS

    67

    http://nodejs.org

  • Back-EndCodeSharingandDistribution:npmnpmisthe"nodepackagemanager".ItinstallswithNodeJS,andgivesyouaccesstoawidevarietyof3rd-partyJavaScriptmodules.

    Italsoperformsdependencymanagementforyourback-endapplication.Youspecifymoduledependenciesinafilecalledpackage.json;runningnpminstallwillresolve,downloadandinstallyourback-endapplication'sdependencies.

    Back-EndCodeSharingandDistribution:npm

    68

    https://www.npmjs.com/

  • ModuleLoading,BundlingandBuildTasks:WebpackWebpackisaJavaScriptmodulebundler.Ittakesmoduleswiththeirdependenciesandgeneratesstaticassetsrepresentingthosemodules.WebpackknownonlyhowtobundleJavaScript.TobundleotherassetslikesCSS,HTML,imagesorjustaboutanythingitusesadditionalloaders.Webpackcanalsobeextendedviaplugins,forexampleminificationandmanglingcanbedoneusingtheUglifyJSpluginforwebpack.

    ModuleLoading,BundlingandBuildTasks:Webpack

    69

    http://webpack.github.io/docs/what-is-webpack.html

  • WebBrowsersWeuseGoogle'sChromebrowserforthiscoursebecauseofitscutting-edgeJavaScriptengineandexcellentdebuggingtools.

    Howeveryouarefreetouseotherbrowsers.Notwellknown,thereisaMozillaFirefoxDeveloperEditionavailablewithsupportforgreatdevelopmentanddebuggingtools.CodewrittenwithJavaScriptshouldworkonanymodernwebbrowser(Firefox,IE9+,Chrome,Safari,Opera).

    Chrome

    70

    https://www.mozilla.org/en-US/firefox/developer/

  • BootstrappinganAngularApplicationBootstrappingisanessentialprocessinAngular-itiswheretheapplicationisloadedwhenAngularcomestolife.

    BootstrappingAngularapplicationsiscertainlydifferentfromAngular1.x,butisstillastraightforwardprocedure.Let'stakealookathowthisisdone.

    BootstrappinganAngularApplication

    71

  • UnderstandingtheFileStructureTogetstartedlet'screateabare-bonesAngularapplicationwithasinglecomponent.Todothisweneedthefollowingfiles:

    app/app.component.ts-thisiswherewedefineourrootcomponentapp/app.module.ts-theentryAngularModuletobebootstrappedindex.html-thisisthepagethecomponentwillberenderedinapp/main.ts-isthegluethatcombinesthecomponentandpagetogether

    app/app.component.ts

    import{Component}from'@angular/core'

    @Component({selector:'app-root',template:'BootstrappinganAngularApplication'})exportclassAppComponent{}

    index.html

    Loading...

    app/app.module.ts

    import{BrowserModule}from'@angular/platform-browser';import{NgModule}'@angular/core';import{AppComponent}from'./app.component'

    @NgModule({imports:[BrowserModule],declarations:[AppComponent],bootstrap:[AppComponent]})exportclassAppModule{}

    app/main.ts

    UnderstandingtheFileStructure

    72

  • import{platformBrowserDynamic}from'@angular/platform-browser-dynamic';import{AppModule}from'./app.module';

    platformBrowserDynamic().bootstrapModule(AppModule);

    Ifyou'remakinguseofAhead-of-Time(AoT)compilation,youwouldcodemain.tsasfollows.

    import{platformBrowser}from'@angular/platform-browser';import{AppModuleNgFactory}from'../aot/app/app.module.ngfactory';

    platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

    ViewExample

    Thebootstrapprocessloadsmain.tswhichisthemainentrypointoftheapplication.TheAppModuleoperatesastherootmoduleofourapplication.ThemoduleisconfiguredtouseAppComponentasthecomponenttobootstrap,andwillberenderedonanyapp-rootHTMLelementencountered.

    ThereisanappHTMLelementintheindex.htmlfile,andweuseapp/main.tstoimporttheAppModulecomponentandtheplatformBrowserDynamic().bootstrapModulefunctionandkickstarttheprocess.Asshownabove,youmayoptionallyuseAoTinwhichcaseyouwillbeworkingwithFactories,intheexample,AppModuleNgFactoryandbootstrapModuleFactory.

    WhydoesAngularbootstrapitselfinthisway?Wellthereisactuallyaverygoodreason.SinceAngularisnotaweb-onlybasedframework,wecanwritecomponentsthatwillruninNativeScript,orCordova,oranyotherenvironmentthatcanhostAngularapplications.

    Themagicistheninourbootstrappingprocess-wecanimportwhichplatformwewouldliketouse,dependingontheenvironmentwe'reoperatingunder.Inourexample,sincewewererunningourAngularapplicationinthebrowser,weusedthebootstrappingprocessfoundin@angular/platform-browser-dynamic.

    It'salsoagoodideatoleavethebootstrappingprocessinitsownseparatemain.tsfile.Thismakesiteasiertotest(sincethecomponentsareisolatedfromthebootstrapcall),easiertoreuseandgivesbetterorganizationandstructuretoourapplication.

    ThereismoretounderstandingAngularModulesand@NgModulewhichwillbecoveredlater,butfornowthisisenoughtogetstarted.

    UnderstandingtheFileStructure

    73

    https://plnkr.co/edit/X0EBXA?p=preview

  • UnderstandingtheFileStructure

    74

  • BootstrappingProvidersThebootstrapprocessalsostartsthedependencyinjectionsysteminAngular.Wewon'tgooverAngular'sdependencyinjectionsystemhere-thatiscoveredlater.Insteadlet'stakealookatanexampleofhowtobootstrapyourapplicationwithapplication-wideproviders.

    Forthis,wewillregisteraservicecalledGreeterServicewiththeproviderspropertyofthemoduleweareusingtobootstraptheapplication.

    app/app.module.ts

    import{BrowserModule}from'@angular/platform-browser';import{NgModule}'@angular/core';import{AppComponent}from'./app.component'import{GreeterService}from'./greeter.service';

    @NgModule({imports:[BrowserModule],providers:[GreeterService],declarations:[AppComponent],bootstrap:[AppComponent]})exportclassAppModule{}

    ViewExample

    BootstrappingProviders

    75

    https://embed.plnkr.co/W8CkQQ62pIjHFr7BqVjX/

  • ComponentsinAngular

    Figure:components

    ThecoreconceptofanyAngularapplicationisthecomponent.Ineffect,thewholeapplicationcanbemodeledasatreeofthesecomponents.

    ThisishowtheAngularteamdefinesacomponent:

    Acomponentcontrolsapatchofscreenrealestatethatwecouldcallaview,anddeclaresreusableUIbuildingblocksforanapplication.

    Basically,acomponentisanythingthatisvisibletotheenduserandwhichcanbereusedmanytimeswithinanapplication.

    InAngular1.xwehadrouterviewsanddirectiveswhichworkedsortoflikecomponents.Theideaofdirectivecomponentsbecamequitepopular.TheywerecreatedbyusingdirectivewithacontrollerwhilerelyingonthecontrollerAsandbindToControllerproperties.Forexample:

    ComponentsinAngular

    76

  • angular.module('ngcourse').directive('ngcHelloComponent',()=>({restrict:'E',scope:{name:'='},template:'Hello,{{ctrl.name}}.',controller:MyComponentCtrl,controllerAs:'ctrl',bindToController:true}));

    Infact,thisconceptbecamesopopularthatinAngular1.5the.componentmethodwasintroducedassyntacticsugar.

    angular.module('ngcourse').component('ngcHelloComponent',{bindings:{name:'='},template:'Hello,{{$ctrl.name}}.',controller:MyComponentCtrl});

    ComponentsinAngular

    77

  • CreatingComponentsComponentsinAngular2builduponthelessonslearnedfromAngular1.5.Wedefineacomponent'sapplicationlogicinsideaclass.Tothisweattach@Component,aTypeScriptdecorator,whichallowsyoutomodifyaclassorfunctiondefinitionandaddsmetadatatopropertiesandfunctionarguments.

    selectoristheelementpropertythatweusetotellAngulartocreateandinsertaninstanceofthiscomponent.templateisaformofHTMLthattellsAngularwhatneedstobetorenderedintheDOM.

    TheComponentbelowwillinterpolatethevalueofnamevariableintothetemplatebetweenthedoublebraces{{name}},whatgetrenderedintheviewis

    HelloWorld

    .

    import{Component}from'@angular/core';

    @Component({selector:'rio-hello',template:'

    Hello,{{name}}!

    ',})exportclassHelloComponent{name:string;

    constructor(){this.name='World';}}

    WeneedtoimporttheComponentdecaratorfrom@angular/corebeforewecanmakeuseofit.TousethiscomponentwesimplyaddtotheHTMLfileoranothertemplate,andAngularwillinsertaninstanceoftheHelloComponentviewbetweenthosetags.

    ViewExample

    CreatingComponents

    78

    http://plnkr.co/edit/bXrxWVkP2MWD8yNDYqVD?p=preview

  • ApplicationStructurewithComponentsAusefulwayofconceptualizingAngularapplicationdesignistolookatitasatreeofnestedcomponents,eachhavinganisolatedscope.

    Forexampleconsiderthefollowing:

    Attherootwehaverio-todo-appwhichconsistsofario-todo-listandario-todo-form.Withinthelistwehaveseveralrio-todo-items.Eachofthesecomponentsisvisibletotheuser,whocaninteractwiththesecomponentsandperformactions.

    ApplicationStructurewithComponents

    79

  • PassingDataintoaComponentTherearetwowaystopassdataintoacomponent,with'propertybinding'and'eventbinding'.InAngular,dataandeventchangedetectionhappenstop-downfromparenttochildren.HoweverforAngulareventswecanusetheDOMeventmentalmodelwhereeventsflowbottom-upfromchildtoparent.So,AngulareventscanbetreatedlikeregularHTMLDOMbasedeventswhenitcomestocancellableeventpropagation.

    The@Input()decoratordefinesasetofparametersthatcanbepasseddownfromthecomponent'sparent.Forexample,wecanmodifytheHelloComponentcomponentsothatnamecanbeprovidedbytheparent.

    import{Component,Input}from'@angular/core';

    @Component({selector:'rio-hello',template:'

    Hello,{{name}}!

    ',})exportclassHelloComponent{@Input()name:string;}

    Thepointofmakingcomponentsisnotonlyencapsulation,butalsoreusability.Inputsallowustoconfigureaparticularinstanceofacomponent.

    Wecannowuseourcomponentlikeso:

    ViewExample

    UnlikeAngular1.x,thisisone-waybinding.

    PassingDataintoaComponent

    80

    http://plnkr.co/edit/LEtEN9?p=preview

  • RespondingtoComponentEventsAneventhandlerisspecifiedinsidethetemplateusingroundbracketstodenoteeventbinding.Thiseventhandleristhencodedintheclasstoprocesstheevent.

    import{Component}from'@angular/core';

    @Component({selector:'rio-counter',template:`

    Count:{{num}}

    Increment`})exportclassCounterComponent{num=0;

    increment(){this.num++;}}

    ViewExample

    Tosenddataoutofcomponentsviaoutputs,startbydefiningtheoutputsattribute.Itacceptsalistofoutputparametersthatacomponentexposestoitsparent.

    app/counter.component.ts

    import{Component,EventEmitter,Input,Output}from'@angular/core';

    @Component({selector:'rio-counter',templateUrl:'app/counter.component.html'})exportclassCounterComponent{@Input()count=0;@Output()result=newEventEmitter();

    increment(){this.count++;this.result.emit(this.count);}}

    RespondingtoComponentEvents

    81

    http://plnkr.co/edit/l4FweMxodN8I26OeqhGH?p=preview

  • app/counter.component.html

    Count:{{count}}

    Increment

    app/app.component.ts

    import{Component,OnChange}from'@angular/core';

    @Component({selector:'rio-app',templateUrl:'app/app.component.html'})exportclassAppComponentimplementsOnChange{num=0;parentCount=0;

    ngOnChange(val:number){this.parentCount=val;}}

    app/app.component.html

    ParentNum:{{num}}
    ParentCount:{{parentCount}}

    ViewExample

    Togetherasetofinput+outputbindingsdefinethepublicAPIofyourcomponent.Inourtemplatesweusethe[squareBrackets]topassinputsandthe(parenthesis)tohandleoutputs.

    RespondingtoComponentEvents

    82

    http://plnkr.co/edit/5RYLZ0?p=preview

  • UsingTwo-WayDataBindingTwo-waydatabindingcombinestheinputandoutputbindingintoasinglenotationusingthengModeldirective.

    Whatthisisdoingbehindthescenesisequivalentto:

    Tocreateyourowncomponentthatsupportstwo-waybinding,youmustdefinean@Outputpropertytomatchan@Input,butsuffixitwiththeChange.Thecodeexamplebelow,insideclassCounterComponentshowshowtomakepropertycountsupporttwo-waybinding.

    app/counter.component.ts

    import{Component,Input,Output,EventEmitter}from'@angular/core';

    @Component({selector:'rio-counter',templateUrl:'app/counter.component.html'})exportclassCounterComponent{@Input()count=0;@Output()countChange=EventEmitter();

    increment(){this.count++;this.countChange.emit(this.count);}}

    app/counter.component.html

    Count:{{count}}-Increment

    UsingTwo-WayDataBinding

    83

  • ViewExample

    UsingTwo-WayDataBinding

    84

    http://plnkr.co/edit/nkww1Ov2AWZRMHFyjhjl?p=preview

  • AccessChildComponentsFromtheTemplateInourtemplates,wemayfindourselvesneedingtoaccessvaluesprovidedbythechildcomponentswhichweusetobuildourowncomponent.

    Themoststraightforwardexamplesofthismaybeseendealingwithformsorinputs:

    app/app.component.html

    NameSubmitFormValue:{{formValue}}

    app/app.component.ts

    import{Component}from'@angular/core';

    @Component({selector:'rio-app',templateUrl:'app/app.component.html'})exportclassAppComponent{formValue=JSON.stringify({});

    onSubmit(form:NgForm){this.formValue=JSON.stringify(form.value);}}

    ViewExample

    Thisisn'tamagicfeaturewhichonlyformsorinputshave,butratherawayofreferencingtheinstanceofachildcomponentinyourtemplate.Withthatreference,youcanthenaccesspublicpropertiesandmethodsonthatcomponent.

    app/app.component.html

    AccessingChildComponentsfromTemplate

    85

    https://plnkr.co/edit/hfv5RC?p=preview

  • Mynameis{{profile.name}}

    app/profile.component.ts

    @Component({selector:'rio-profile',templateUrl:'app/profile.component.html'})exportclassProfileComponent{name='JohnDoe';}

    ViewExample

    Thereareothermeansofaccessingandinterfacingwithchildcomponents,butifyousimplyneedtoreferencepropertiesormethodsofachild,thiscanbeasimpleandstraightforwardmethodofdoingso.

    AccessingChildComponentsfromTemplate

    86

    https://plnkr.co/edit/wEFOta?p=preview

  • ProjectionProjectionisaveryimportantconceptinAngular.Itenablesdeveloperstobuildreusablecomponentsandmakeapplicationsmorescalableandflexible.Toillustratethat,supposewehaveaChildComponentlike:

    @Component({selector:'rio-child',template:`ChildComponent{{childContent}}`})exportclassChildComponent{childContent="Defaultcontent";}

    Whatshouldwedoifwewanttoreplace{{childContent}}toanyHTMLthatprovidedtoChildComponent?Onetemptingideaistodefinean@Inputcontainingthetext,butwhatifyouwantedtoprovidestyledHTML,orothercomponents?Tryingtohandlethiswithan@Inputcangetmessyquickly,andthisiswherecontentprojectioncomesin.Componentsbydefaultsupportprojection,andyoucanusethengContentdirectivetoplacetheprojectedcontentinyourtemplate.

    So,changeChildComponenttouseprojection:

    app/child/child.component.ts

    import{Component}from'@angular/core';

    @Component({selector:'rio-child',template:`ChildComponent`})exportclassChildComponent{}

    Then,whenweuseChildComponentinthetemplate:

    Projection

    87

  • app/app.component.html

    ...

    Myprojectedcontent.

    ...

    ThisistellingAngular,thatforanymarkupthatappearsbetweentheopeningandclosingtagof,toplaceinsideof.

    Whendoingthis,wecanhaveothercomponents,markup,etcprojectedhereandtheChildComponentdoesnotneedtoknowaboutorcarewhatisbeingprovided.

    ViewExample

    Butwhatifwehavemultipleandwanttospecifythepositionoftheprojectedcontenttocertainng-content?Forexample,forthepreviousChildComponent,ifwewanttoformattheprojectedcontentintoanextraheaderandfootersection:

    app/child-select.component.html

    ChildComponentwithSelect

    Theninthetemplate,wecanusedirectives,say,tospecifythepositionofprojectedcontenttotheng-contentwithselect="header":

    app/app.component.html

    Projection

    88

    http://plnkr.co/edit/QAQ6BFuwuzEDVvqAmN9L?p=preview

  • ...

    SectionContentdivwith.class-selectFooterContentHeaderContent

    ...

    Besidesusingdirectives,developerscanalsoselectang-contentthroughcssclass:

    app/app.component.html

    divwith.class-select

    ViewExample

    Projection

    89

    http://plnkr.co/edit/rH2vGgFluLXHCsgfkNjF?p=preview

  • StructuringApplicationswithComponentsAsthecomplexityandsizeofourapplicationgrows,wewanttodivideresponsibilitiesamongourcomponentsfurther.

    Smart/Containercomponentsareapplication-specific,higher-level,containercomponents,withaccesstotheapplication'sdomainmodel.

    Dumb/PresentationalcomponentsarecomponentsresponsibleforUIrenderingand/orbehaviorofspecificentitiespassedinviacomponentsAPI(i.ecomponentpropertiesandevents).Thosecomponentsaremorein-linewiththeupcomingWebComponentstandards.

    StructuringApplicationswithComponents

    90

  • UsingOtherComponentsComponentsdependonothercomponents,directivesandpipes.Forexample,TodoListComponentreliesonTodoItemComponent.Toletacomponentknowaboutthesedependencieswegroupthemintoamodule.

    import{NgModule}from'@angular/core';

    import{TodoListComponent}from'./components/todo-list.component';import{TodoItemComponent}from'./components/todo-item.component';import{TodoInputComponent}from'./components/todo-input.component';

    @NgModule({imports:[...],declarations:[TodoListComponent,TodoItemComponent,TodoInputComponent],bootstrap:[...]})exportclassToDoAppModule{}

    Thepropertydeclarationsexpectsanarrayofcomponents,directivesandpipesthatarepartofthemodule.

    PleaseseetheModulessectionformoreinfoaboutNgModule.

    UsingOtherComponents

    91

  • DirectivesADirectivemodifiestheDOMtochangeapperance,behaviororlayoutofDOMelements.DirectivesareoneofthecorebuildingblocksAngularusestobuildapplications.Infact,Angularcomponentsareinlargepartdirectiveswithtemplates.

    FromanAngular1.xperspective,Angular2componentshaveassumedalotoftherolesdirectivesusedto.Themajorityofissuesthatinvolvetemplatesanddependencyinjectionruleswillbedonethroughcomponents,andissuesthatinvolvemodifyinggenericbehaviourisdonethroughdirectives.

    TherearethreemaintypesofdirectivesinAngular:

    Component-directivewithatemplate.Attributedirectives-directivesthatchangethebehaviorofacomponentorelementbutdon'taffectthetemplateStructuraldirectives-directivesthatchangethebehaviorofacomponentorelementbyaffectinghowthetemplateisrendered

    Directives

    92

  • AttributeDirectivesAttributedirectivesareawayofchangingtheappearanceorbehaviorofacomponentoranativeDOMelement.Ideally,adirectiveshouldworkinawaythatiscomponentagnosticandnotboundtoimplementationdetails.

    Forexample,Angularhasbuilt-inattributedirectivessuchasngClassandngStylethatworkonanycomponentorelement.

    AttributeDirectives

    93

  • NgStyleDirectiveAngularprovidesabuilt-indirective,ngStyle,tomodifyacomponentorelement'sstyleattribute.Here'sanexample:

    @Component({selector:'app-style-example',template:`

    `})exportclassStyleExampleComponent{borderStyle='1pxsolidblack';}

    ViewExample

    Noticethatbindingadirectiveworkstheexactsamewayascomponentattributebindings.Here,we'rebindinganexpression,anobjectliteral,tothengStyledirectivesothedirectivenamemustbeenclosedinsquarebrackets.ngStyleacceptsanobjectwhosepropertiesandvaluesdefinethatelement'sstyle.Inthiscase,wecanseethatbothkebabcaseandlowercamelcasecanbeusedwhenspecifyingastyleproperty.AlsonoticethatboththehtmlstyleattributeandAngularngStyledirectivearecombinedwhenstylingtheelement.

    Wecanremovethestylepropertiesoutofthetemplateintothecomponentasapropertyobject,whichthengetsassignedtoNgStyleusingpropertybinding.Thisallowsdynamicchangestothevaluesaswellasprovidestheflexibilitytoaddandremovestyleproperties.

    NgStyleDirective

    94

    https://plnkr.co/edit/akK3Gw8W6EgUQ4PRQp4h?p=preview

  • @Component({selector:'app-style-example',template:`

    `})exportclassStyleExampleComponent{borderStyle='1pxsolidblack';

    alertStyles={'color':'red','font-weight':'bold','borderBottom':this.borderStyle};}

    NgStyleDirective

    95

  • NgClassDirectiveThengClassdirectivechangestheclassattributethatisboundtothecomponentorelementit'sattachedto.Thereareafewdifferentwaysofusingthedirective.

    BindingastringWecanbindastringdirectlytotheattribute.Thisworksjustlikeaddinganhtmlclassattribute.

    @Component({selector:'app-class-as-string',template:`

    `,styles:[`.centered-text{text-align:center;}

    .underlined{border-bottom:1pxsolid#ccc;}

    .orange{color:orange;}`]})exportclassClassAsStringComponent{}

    ViewExample

    Inthiscase,we'rebindingastringdirectlysoweavoidwrappingthedirectiveinsquarebrackets.AlsonoticethatthengClassworkswiththeclassattributetocombinethefinalclasses.

    Bindinganarray

    NgClassDirective

    96

    https://plnkr.co/edit/uUtjY1Qlkx5dOB8gsqCm?p=preview

  • @Component({selector:'app-class-as-array',template:`

    `,styles:[`.warning{color:red;font-weight:bold;}

    .big{font-size:1.2rem;}`]})exportclassClassAsArrayComponent{}

    ViewExample

    Here,sincewearebindingtothengClassdirectivebyusinganexpression,weneedtowrapthedirectivenameinsquarebrackets.Passinginanarrayisusefulwhenyouwanttohaveafunctionputtogetherthelistofapplicableclassnames.

    BindinganobjectLastly,anobjectcanbeboundtothedirective.Angularapplieseachpropertynameofthatobjecttothecomponentifthatpropertyistrue.

    NgClassDirective

    97

    https://plnkr.co/edit/uUtjY1Qlkx5dOB8gsqCm?p=preview

  • @Component({selector:'app-class-as-object',template:`


    ToggleFlat

    `,styles:[`.card{border:1pxsolid#eee;padding:1rem;margin:0.4rem;font-family:sans-serif;box-shadow:2px2px2px#888888;}

    .dark{background-color:#444;border-color:#000;color:#fff;}

    .flat{box-shadow:none;}`]})exportclassClassAsObjectComponent{flat:boolean=true;}

    ViewExample

    Herewecanseethatsincetheobject'scardandflatpropertiesaretrue,thoseclassesareappliedbutsincedarkisfalse,it'snotapplied.

    NgClassDirective

    98

    https://plnkr.co/edit/uUtjY1Qlkx5dOB8gsqCm?p=preview

  • StructuralDirectivesStructuralDirectivesareawayofhandlinghowacomponentorelementrendersthroughtheuseofthetemplatetag.Thisallowsustorunsomecodethatdecideswhatthefinalrenderedoutputwillbe.Angularhasafewbuilt-instructuraldirectivessuchasngIf,ngFor,andngSwitch.

    Note:Forthosewhoareunfamiliarwiththetemplatetag,itisanHTMLelementwithafewspecialproperties.Contentnestedinatemplatetagisnotrenderedonpageloadandissomethingthatismeanttobeloadedthroughcodeatruntime.Formoreinformationonthetemplatetag,visittheMDNdocumentation.

    Structuraldirectiveshavetheirownspecialsyntaxinthetemplatethatworksassyntacticsugar.

    @Component({selector:'app-directive-example',template:`

    Underastructuraldirective.

    `})

    Insteadofbeingenclosedbysquarebrackets,ourdummystructuraldirectiveisprefixedwithanasterisk.Noticethatthebindingisstillanexpressionbindingeventhoughtherearenosquarebrackets.That'sduetothefactthatit'ssyntacticsugarthatallowsusingthedirectiveinamoreintuitivewayandsimilartohowdirectiveswereusedinAngular1.Thecomponenttemplateaboveisequivalenttothefollowing:

    @Component({selector:'app-directive-example',template:`

    Underastructuraldirective.

    `})

    Here,weseewhatwasmentionedearlierwhenwesaidthatstructuraldirectivesusethetemplatetag.Angularalsohasabuilt-intemplatedirectivethatdoesthesamething:

    StructuralDirectives

    99

    https://developer.mozilla.org/en/docs/Web/HTML/Element/template

  • @Component({selector:'app-directive-example',template:`

    Underastructuraldirective.

    `})

    StructuralDirectives

    100

  • NgIfDirectiveThengIfdirectiveconditionallyaddsorremovescontentfromtheDOMbasedonwhetherornotanexpressionistrueorfalse.

    Here'sourappcomponent,wherewebindthengIfdirectivetoanexamplecomponent.

    @Component({selector:'app-root',template:`ToggleComponentHello`})exportclassAppComponent{exists=true;

    toggleExists(){this.exists=!this.exists;}}

    ViewExample

    ClickingthebuttonwilltogglewhetherornotIfExampleComponentisapartoftheDOMandnotjustwhetheritisvisibleornot.Thismeansthateverytimethebuttonisclicked,IfExampleComponentwillbecreatedordestroyed.Thiscanbeanissuewithcomponentsthathaveexpensivecreate/destroyactions.Forexample,acomponentcouldhavealargechildsubtreeormakeseveralHTTPcallswhenconstructed.InthesecasesitmaybebettertoavoidusingngIfifpossible.

    NgIfDirective

    101

    https://plnkr.co/edit/Kb0KW89265F0e9pYJ118?p=preview

  • NgForDirectiveTheNgFordirectiveisawayofrepeatingatemplatebyusingeachitemofaniterableasthattemplate'scontext.

    @Component({selector:'app-root',template:`{{episode.title}}`})exportclassAppComponent{episodes=[{title:'WinterIsComing',director:'TimVanPatten'},{title:'TheKingsroad',director:'TimVanPatten'},{title:'LordSnow',director:'BrianKirk'},{title:'Cripples,Bastards,andBrokenThings',director:'BrianKirk'},{title:'TheWolfandtheLion',director:'BrianKirk'},{title:'AGoldenCrown',director:'DanielMinahan'},{title:'YouWinorYouDie',director:'DanielMinahan'},{title:'ThePointyEnd',director:'DanielMinahan'}];}

    ViewExample

    TheNgFordirectivehasadifferentsyntaxfromotherdirectiveswe'veseen.Ifyou'refamiliarwiththefor...ofstatement,you'llnoticethatthey'realmostidentical.NgForletsyouspecifyaniterableobjecttoiterateoverandthenametorefertoeachitembyinsidethescope.Inourexample,youcanseethatepisodeisavailableforinterpolationaswellaspropertybinding.Thedirectivedoessomeextraparsingsothatwhenthisisexpandedtotemplateform,itlooksabitdifferent:

    @Component({selector:'app',template:`{{episode.title}}`})

    NgForDirective

    102

    https://plnkr.co/edit/dXU4K13piTYotDX5Nhi6?p=previewhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

  • ViewExample

    Noticethatthereisanoddlet-episodepropertyonthetemplateelement.TheNgFordirectiveprovidessomevariablesascontextwithinitsscope.let-episodeisacontextbindingandhereittakesonthevalueofeachitemoftheiterable.

    LocalVariablesNgForalsoprovidesothervaluesthatcanbealiasedtolocalvariables:

    index-positionofthecurrentitemintheiterablestartingat0first-trueifthecurrentitemisthefirstitemintheiterablelast-trueifthecurrentitemisthelastitemintheiterableeven-trueifthecurrentindexisanevennumberodd-trueifthecurrentindexisanoddnumber

    @Component({selector:'app-root',template:`{{i+1}}.{{episode.title}}

    Desugared

    {{i+1}}.{{episode.title}}`})

    ViewExample

    trackBy

    NgForDirective

    103

    https://plnkr.co/edit/dXU4K13piTYotDX5Nhi6?p=previewhttps://plnkr.co/edit/58A5p8cWpVIY7Ne4O7aO?p=preview

  • OftenNgForisusedtoiteratethroughalistofobjectswithauniqueIDfield.Inthiscase,wecanprovideatrackByfunctionwhichhelpsAngularkeeptrackofitemsinthelistsothatitcandetectwhichitemshavebeenaddedorremovedandimproveperformance.

    Angularwilltryandtrackobjectsbyreferencetodeterminewhichitemsshouldbecreatedanddestroyed.However,ifyoureplacethelistwithanewsourceofobjects,perhapsasaresultofanAPIrequest-wecangetsomeextraperformancebytellingAngularhowwewanttokeeptrackofthings.

    Forexample,iftheAddEpisodebuttonwastomakearequestandreturnanewlistofepisodes,wemightnotwanttodestroyandre-createeveryiteminthelist.IftheepisodeshaveauniqueID,wecouldaddatrackByfunction:

    NgForDirective

    104

  • @Component({selector:'app-root',template:`AddEpisode{{episode.title}}`})exportclassAppComponent{

    otherEpisodes=[{title:'TwoSwords',director:'D.B.Weiss',id:8},{title:'TheLionandtheRose',director:'AlexGraves',id:9},{title:'BreakerofChains',director:'MichelleMacLaren',id:10},{title:'Oathkeeper',director:'MichelleMacLaren',id:11}]

    episodes=[{title:'WinterIsComing',director:'TimVanPatten',id:0},{title:'TheKingsroad',director:'TimVanPatten',id:1},{title:'LordSnow',director:'BrianKirk',id:2},{title:'Cripples,Bastards,andBrokenThings',director:'BrianKirk',id:3},{title:'TheWolfandtheLion',director:'BrianKirk',id:4},{title:'AGoldenCrown',director:'DanielMinahan',id:5},{title:'YouWinorYouDie',director:'DanielMinahan',id:6}{title:'ThePointyEnd',director:'DanielMinahan',id:7}];

    addOtherEpisode(){//WewanttocreateanewobjectreferenceforsakeofexampleletepisodesCopy=JSON.parse(JSON.stringify(this.episodes))this.episodes=[...episodesCopy,this.otherEpisodes.pop()];}trackById(index:number,episode:any):number{returnepisode.id;}}

    ToseehowthiscanaffecttheForExamplecomponent,let'saddsomeloggingtoit.

    NgForDirective

    105

  • exportclassForExampleComponent{@Input()episode;

    ngOnInit(){console.log('componentcreated',this.episode)}ngOnDestroy(){console.log('destroyingcomponent',this.episode)}}

    ViewExample

    Whenweviewtheexample,asweclickonAddEpisode,wecanseeconsoleoutputindicatingthatonlyonecomponentwascreated-forthenewlyaddeditemtothelist.

    However,ifweweretoremovethetrackByfromthe*ngFor-everytimeweclickthebutton,wewouldseetheitemsinthecomponentgettingdestroyedandrecreated.

    ViewExampleWithouttrackBy

    NgForDirective

    106

    https://plnkr.co/edit/jQmozF?p=previewhttps://plnkr.co/edit/hC2cIK?p=preview

  • NgSwitchDirectivesngSwitchisactuallycomprisedoftwodirectives,anattributedirectiveandastructuraldirective.It'sverysimilartoaswitchstatementinJavaScriptandotherprogramminglanguages,butinthetemplate.

    @Component({selector:'app-root',template:`Tab1Tab2Tab3

    Tabcontent1Tabcontent2Selectatab`})exportclassAppComponent{tab:number=0;

    setTab(num:number){this.tab=num;}

    isSelected(num:number){returnthis.tab===num;}}

    ViewExample

    HereweseethengSwitchattributedirectivebeingattachedtoanelement.Thisexpressionboundtothedirectivedefineswhatwillcomparedagainstintheswitchstructuraldirectives.IfanexpressionboundtongSwitchCasematchestheonegiventongSwitch,thosecomponentsarecreatedandtheothersdestroyed.Ifnoneofthecasesmatch,thencomponentsthathavengSwitchDefaultboundtothemwillbecreatedandtheothersdestroyed.NotethatmultiplecomponentscanbematchedusingngSwitchCaseandinthosecasesallmatchingcomponentswillbecreated.Sincecomponentsarecreatedordestroyedbeawareofthecostsindoingso.

    NgSwitchDirectives

    107

    https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/switchhttps://plnkr.co/edit/QWxD0DIZi6QiISafwfgu?p=preview

  • NgSwitchDirectives

    108

  • UsingMultipleStructuralDirectivesSometimeswe'llwanttocombinemultiplestructuraldirectivestogether,likeiteratingusingngForbutwantingtodoanngIftomakesurethatthe