sathyalog.files.wordpress.com · 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...

460

Upload: others

Post on 23-May-2020

23 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

    WhyAngular2?

    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

    BootstrappinganAngular2Application

    UnderstandingtheFileStructure

    BootstrappingProviders

    ComponentsinAngular2

    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

    11.1

    11.1.1

    11.1.2

    11.1.3

    11.1.4

    11.1.5

    11.1.6

    12.1

    Observables

    UsingObservables

    ErrorHandling

    DisposingSubscriptionsandReleasingResources

    ObservablesvsPromises

    UsingObservablesFromOtherSources

    ObservablesArrayOperations

    ColdvsHotObservables

    Summary

    Angular2DependencyInjection

    WhatisDI?

    DIFramework

    Angular2'sDI

    @Inject()and@Injectable

    InjectionBeyondClasses

    AvoidingInjectionCollisions:OpaqueToken

    TheInjectorTree

    Http

    MakingRequests

    CatchingRejections

    CatchandRelease

    CancelaRequest

    Retry

    Searchwithflatmap

    RequestsasPromises

    ChangeDetection

    ChangeDetectionStrategiesinAngular1vsAngular2

    HowChangeDetectionWorks

    ChangeDetectorClasses

    ChangeDetectionStrategy:OnPush

    EnforcingImmutability

    AdditionalResources

    Zone.js

    4

  • 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

    16.1.2.1

    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

    NestingFormData

    5

  • 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.2

    19.1.3

    19.1.4

    19.1.5

    UsingTemplateModelBinding

    ValidatingTemplate-DrivenForms

    Reactive/Model-DrivenForms

    FormBuilderBasics

    ValidatingFormBuilderForms

    FormBuilderCustomValidation

    VisualCuesforUsers

    Modules

    WhatisanAngular2Module?

    AddingComponents,PipesandServicestoaModule

    CreatingaFeatureModule

    DirectiveDuplications

    LazyLoadingaModule

    LazyLoadingandtheDependencyInjectionTree

    SharedModulesandDependencyInjection

    SharingtheSameDependencyInjectionTree

    Routing

    WhyRouting?

    ConfiguringRoutes

    RedirectingtheRoutertoAnotherRoute

    DefiningLinksBetweenRoutes

    DynamicallyAddingRouteComponents

    UsingRouteParameters

    DefiningChildRoutes

    ControllingAccesstoorfromaRoute

    PassingOptionalParameterstoaRoute

    UsingAuxiliaryRoutes

    ReduxandNgrx

    ReviewofReducersandPureFunctions

    ReducersasStateManagement

    ReduxActions

    ConfiguringyourApplicationtouseRedux

    UsingReduxwithComponents

    6

  • 19.1.6

    19.1.7

    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

    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

    ReduxandComponentArchitecture

    GettingMoreFromReduxandNgrx

    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

    TestingRedux

    TestingSimpleActions

    TestingComplexActions

    TestingReducers

    Afterthoughts

    MigratingAngular1.xProjectstoAngular2

    MigrationPrep

    UpgradingToAngular1.3+Style

    UsingWebpack

    7

  • 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

    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

    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

    CreatingaNewApp

    ServingtheApp

    CreatingComponents

    CreatingRoutes

    CreatingOtherThings

    Testing

    Linting

    CLICommandOverview

    AddingThirdPartyLibraries

    8

  • 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

    IntegratinganExistingApp

    AccessibilityinAngular2

    WhyMakemyApplicationAccessible?

    KeyConcernsofAccessibleWebApplications

    SemanticMarkup

    KeyboardAccessibility

    VisualAssistance

    TestingforAccessibility

    IsmyApplicationReadable?

    IsmyApplicationPredictable?

    IsmyApplicationNavigable?

    TestingwithScreenReaders

    AdditionalResources

    InternationalizationinAngular2

    Whatistheprocesslikeandhowisinvolved?

    Markingtextinourtemplates

    ExtractingtranslationtextusingtheAngularCLI

    Howtoimportthecompletedtranslationfiles

    UsingtheAoTCompiler

    UsingtheJiTCompiler

    Glossary

    FurtherReadingAndReference

    9

  • Rangle'sAngular2TrainingBook

    Overthelastthreeandahalfyears,AngularJShasbecometheleadingopensourceJavaScriptapplicationframeworkforhundredsofthousandsofprogrammersaroundtheworld.The"1.x"versionofAngularJShasbeenwidelyusedandbecameextremelypopularforcomplexapplications.Thenew"Angular2"hasalsoannounceditsfinalreleaseversion.

    AboutRangle’sAngular2TrainingBookWedevelopedthisbooktobeusedascoursematerialforRangle'sAngular2training,butmanypeoplehavefoundittobeusefulforlearningAngular2ontheirown.ThisbookwillcoverthemostimportantAngular2topics,fromgettingstartedwiththeAngular2toolchaintowritingAngular2applicationsinascalableandmaintainablemanner.

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

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

    Introduction

    10

    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

    11

  • 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

    12

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

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

    Angular2'sAdvantagesThefirstreleaseofAngularprovidedprogrammerswiththetoolstodevelopandarchitectlargescaleJavaScriptapplications,butitsagehasrevealedanumberofflawsandsharpedges.Angular2wasbuiltonfiveyearsofcommunityfeedback.

    Angular2IsEasier

    ThenewAngular2codebaseismoremodern,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.

    WhyAngular2?

    13

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

  • Byfocusingonmakingtheframeworkeasierforcomputerstoprocess,Angular2allowsforamuchricherdevelopmentecosystem.Programmersusingsophisticatedtexteditors(orIDEs)willnoticedramaticimprovementswithauto-completionandtypesuggestions.TheseimprovementshelptoreducethecognitiveburdenoflearningAngular2.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,providinganotherwaytoleveragenativedevicefeatureswithAngular2.

    ProjectArchitectureandMaintenance

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

    WhyAngular2?

    14

    https://www.nativescript.org/

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

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

    NewFeatures

    SomeoftheotherinterestingfeaturesinAngular2are:

    FormBuilderChangeDetectionTemplatingRoutingAnnotationsObservablesShadowDOM

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

    WhyAngular2?

    15

  • 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

    WhyAngular2?

    16

  • EcmaScript6andTypeScriptFeatures

    Figure:ES6andTypeScript

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

    ES6isnotwidelysupportedintoday'sbrowsers,soitneedstobetranspiledtoES5.Youcanchoosebetweenseveraltranspilers,butwe'llbeusingTypeScript,whichiswhattheAngularteamusestowriteAngular2.Angular2makesuseofanumberoffeaturesofES6andTypeScript.

    EcmaScript6andTypeScriptFeatures

    17

  • ES6JavaScriptwascreatedin1995,butthelanguageisstillthrivingtoday.Therearesubsets,supersets,currentversionsandthelatestversionES6thatbringsalotofnewfeatures.

    Someofthehighlights:

    ClassesArrowFunctionsTemplateStringsInheritanceConstantsandBlockScopedVariablesSpreadandRestoperatorsDestructuringModules

    ES6

    18

  • 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

    19

  • Classes

    20

  • 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.Thisrarelywhatyouwant,anditcanbeconfusingwhenthisisnotwhatyouwereexpecting,becauseofwherethefunctionwascalledfrom.In"strict"mode,thiswouldbeundefined,whichisslightlylessconfusing.

    Refresheron'this'

    21

  • 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'

    22

    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

    23

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

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

    ctrl.outputList();

    Let'strythiscodeonES6Fiddle(http://www.es6fiddle.net/).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!)}}

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

    Herethisinsidethearrowfunctionreferstotheinstancevariable.

    Warningarrowfunctionsdonothavetheirownargumentsvariable,whichcanbeconfusingtoveteranJavaScriptprogrammers.superandnew.targetarealsoscopedfromtheouterenclosure.

    ArrowFunctions

    24

    http://www.es6fiddle.net/

  • 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

    25

  • InheritanceJavaScript'sinheritanceworksdifferentlyfrominheritanceinotherlanguages,whichcanbeveryconfusing.ES6classesprovideasyntacticsugarattemptingtoalleviatetheissueswithusingprototypicalinheritancepresentinES5.

    Toillustratethis,let'simagewehaveazooapplicationwheretypesofbirdsarecreated.Inclassicalinheritance,wedefineabaseclassandthensubclassittocreateaderivedclass.

    SubclassingTheexamplecodebelowshowshowtoderivePenguinfromBirdusingtheextendskeyword.AlsopayattentiontothesuperkeywordusedinthesubclassconstructorofPenguin,itisusedtopasstheargumenttothebaseclassBird'sconstructor.

    TheBirdclassdefinesthemethodwalkwhichisinheritedbythePenguinclassandisavailableforusebyinstanceofPenguinobjects.LikewisethePenguinclassdefinesthemethodswimwhichisnotavilabletoBirdobjects.Inheritanceworkstop-downfrombaseclasstoitssubclass.

    ObjectInitializationTheclassconstructoriscalledwhenanobjectiscreatedusingthenewoperator,itwillbecalledbeforetheobjectisfullycreated.Aconsturctorisusedtopassinargumentstoinitializethenewlycreatedobject.

    Theorderofobjectcreationstartsfromitsbaseclassandthenmovesdowntoanysubclass(es).

    Inheritance

    26

  • //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

    27

  • //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

    28

  • DelegationIntheinheritancesectionwelookedatonewaytoextendaclassfunctionality,thereissecondwayusingdelegationtoextendfunctionality.Withdelegation,oneobjectwillcontainareferencetoadifferentobjectthatitwillhandoffarequesttoperformthefunctionality.

    ThecodebelowshowshowtousedelegationwiththeBirdclassandPenguinclass.ThePenguinclasshasareferencetotheBirdclassanditdelegratescallmadetoit'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

    29

    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

    30

  • 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

    31

  • Theexampleabovedemonstratesthatweareabletochangethenamepropertyofobjectperson,butweareunabletoresetthereferencepersonsinceithasbeenmarkedasconst.

    ConstReferenceToAnObjectSomethingsimilartotheabovecodeisusingaconstreference,belowwe'veswitchtousingletfortheliteralobject.

    letperson={name:'Tammy'};

    constp=person;

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

    p=null;//"TypeError:Assignmenttoconstantvariable.

    Takeaway,markinganobjectreferenceconstdoesnotmakepropertiesinsidetheobjectconst.

    Ref:.

    ConstantsandBlockScopedVariables

    32

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

  • OperatorsSpreadandRestASpreadoperatorallowsin-placeexpansionofanexpressionforthefollowingcases:

    1. Array2. Functioncall3. Multiplevariabledestructuring

    TheRestoperatorworksintheoppositedirectionofthespreadoperator,itcollectsanindefinitenumberofcommaseparatedexpressionsintoanarray.

    OperatorSpreadSpreadexample:

    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}

    OperatorRestRestargumentssharetheellipsislikesyntaxofrestoperatorsbutareusedforadifferentpurpose.Restargumentsareusedtoaccessavariablenumberofargumentspassedtoafunction.Forexample:

    ...spreadand...rest

    33

  • 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.

    Restargumentsareinfactarrays.Theotherimportantdifferenceisthatrestargumentsonlyincludeargumentsnotspecificallynamedinafunctionlikeso:

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

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

    ...spreadand...rest

    34

  • 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

    35

    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

    36

    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,whichwasintroducedinES6,andisashortformforthefollowing.

    exportfunctioncircumference(diameter){returndiameter*pi;}

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

    Wewon'tgetintothevariousmodulesystemsoutthere,butit'sworthunderstandingtherearevariousmoduleloadersavailable.Thepopularchoicesoutthereare:

    RequireJSSystemJSWebpack

    LoadingaModuleFromaBrowser

    Modules

    37

  • BelowwemakeuseofSystemJStoloadamodule.ThescriptfirstloadsthecodefortheSystemJSlibrary,thenthefunctioncallSystem.importisusetoimport(load)theappmodule.

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

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

    Modules

    38

  • 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

    39

  • 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

    40

  • 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

    41

    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.

    ForAngular2projectsthereareanumberofspecificsettingsthatneedtobeconfiguredinaproject'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

    42

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

    Decorators

    DecoratorsupportinTypeScripthasn'tbeenfinalizedyetbutsinceAngular2usesdecoratorsextensively,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

    43

    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

    44

  • 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

    45

  • 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

    46

  • 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

    47

  • 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

    48

  • 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

    49

  • interfaceAction{type:string;}

    leta:Action={type:'literal'}

    Interfaces

    50

  • 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

    51

  • 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

    52

  • 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

    53

  • 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

    54

  • 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

    55

  • Toillustratethehowmuchthetypekeywordimprovedthereadabilityoftheprevioussnippet,hereisthefunctiontypedefinedinline.

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

    TypeKeyword

    56

  • DecoratorsDecoratorsareproposedforafutureversionofJavaScript,buttheAngular2teamreallywantedtousethem,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;

    ReaderswhohaveplayedwithAngular2willnoticethatthesesignaturesdonotlooklikethesignaturesusedbyAngular2specificdecoratorslike@Component().

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

    Ifdecoratorsstilllookconfusing,perhapssomeexampleswillclearthingsup.

    Decorators

    57

  • 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

    58

  • PropertyDecorators

    59

  • 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

    60

  • ClassDecorators

    61

  • 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.ReadersfamiliarwithAngular2cannowimaginehowAngular2implementedtheir@Inject()system.

    ParameterDecorators

    62

  • TheJavaScriptToolchainInthissection,we'lldescribethetoolsthatyou'llbeusingfortherestofthecourse.

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

    TheJavaScriptToolchain

    63

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

    Gitisadecentralizeddistributedversioningsystem,itallowsprogrammerstocollaborateonthesamecodebasewithoutsteppingoneachother'stoes.Ithasbecomethede-factosourcecontrolsystemforopensourcedevelopmentbecauseofitsdecentralizedmodelandcheapbranchingfeatures.

    FormoreinformationonhowtouseGit,headovertoProGit

    SourceControl:git

    64

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

  • TheCommandLineJavaScriptdevelopmenttoolsareverycommandlineoriented.IfyoucomefromaWindowsbackgroundyoumayfindthisunfamiliar.Howeverthecommandlineprovidesbettersupportforautomatingdevelopmenttasks,soit'sworthgettingcomfortablewithit.

    Wewillprovideexamplesforallcommandlineactivitiesrequiredbythiscourse.

    TheCommandLine

    65

  • 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

    66

    http://nodejs.org

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

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

    Back-EndCodeSharingandDistribution:npm

    67

    https://www.npmjs.com/

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

    ModuleLoading,BundlingandBuildTasks:Webpack

    68

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

  • WebBrowsersWeuseGoogle'sChromebrowserforthiscoursebecauseofitscutting-edgeJavaScriptengineandexcellentdebuggingtools.

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

    Chrome

    69

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

  • BootstrappinganAngular2ApplicationBootstrappingisanessentialprocessinAngular-itiswheretheapplicationisloadedwhenAngularcomestolife.

    BootstrappingAngular2applicationsiscertainlydifferentfromAngular1.x,butisstillastraightforwardprocedure.Let'stakealookathowthisisdone.

    BootstrappinganAngular2Application

    70

  • UnderstandingtheFileStructureTogetstartedlet'screateabare-bonesAngular2applicationwithasinglecomponent.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:'BootstrappinganAngular2Application'})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

    71

  • 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.

    WhydoesAngular2bootstrapitselfinthisway?Wellthereisactuallyaverygoodreason.SinceAngular2isnotaweb-onlybasedframework,wecanwritecomponentsthatwillruninNativeScript,orCordova,oranyotherenvironmentthatcanhostAngular2applications.

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

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

    ThereismoretounderstandingAngularModulesand@NgModulewhichwillbecoveredlater,butfornowthisisenoughtogetstarted.

    UnderstandingtheFileStructure

    72

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

  • UnderstandingtheFileStructure

    73

  • BootstrappingProvidersThebootstrapprocessalsostartsthedependencyinjectionsysteminAngular2.Wewon'tgooverAngular2'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

    74

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

  • ComponentsinAngular2

    Figure:components

    ThecoreconceptofanyAngular2applicationisthecomponent.Ineffect,thewholeapplicationcanbemodeledasatreeofthesecomponents.

    ThisishowtheAngular2teamdefinesacomponent:

    Acomponentcontrolsapatchofscreenrealestatethatwecouldcallaview,anddeclaresreusableUIbuildingblocksforanapplication.

    Basically,acomponentisanythingthatisvisibletotheenduserandwhichcanbereusedmanytimeswithinanapplication.

    InAngular1.xwehadrouterviewsanddirectiveswhichworkedsortoflikecomponents.Theideaofdirectivecomponentsbecamequitepopular.TheywerecreatedbyusingdirectivewithacontrollerwhilerelyingonthecontrollerAsandbindToControllerproperties.Forexample:

    ComponentsinAngular2

    75

  • 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});

    ComponentsinAngular2

    76

  • 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

    77

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

  • ApplicationStructurewithComponentsAusefulwayofconceptualizingAngularapplicationdesignistolookatitasatreeofnestedcomponents,eachhavinganisolatedscope.

    Forexampleconsiderthefollowing:

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

    ApplicationStructurewithComponents

    78

  • PassingDataintoaComponentTherearetwowaystopassdataintoacomponent,with'propertybinding'and'eventbinding'.InAngular2,dataandeventchangedetectionhappenstop-downfromparenttochildren.HoweverforAngular2eventswecanusetheDOMeventmentalmodelwhereeventsflowbottom-upfromchildtoparent.So,Angular2eventscanbetreatedlikeregularHTMLDOMbasedeventswhenitcomestocancellableeventpropagation.

    The@Input()decaratordefinesasetofparametersthatcanbepasseddownfromthecomponent'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

    79

    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

    80

    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

    81

    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

    82

  • ViewExample

    UsingTwo-WayDataBinding

    83

    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

    84

    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

    85

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

  • ProjectionProjectionisaveryimportantconceptinAngular2.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

    86

  • 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

    87

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

  • ...

    SectionContentdivwith.class-selectFooterContentHeaderContent

    ...

    Besidesusingdirectives,developerscanalsoselectang-contentthroughcssclass:

    app/app.component.html

    divwith.class-select

    ViewExample

    Projection

    88

    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

    89

  • 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

    90

  • DirectivesADirectivemodifiestheDOMtochangeapperance,behaviororlayoutofDOMelements.DirectivesareoneofthecorebuildingblocksAngular2usestobuildapplications.Infact,Angular2componentsareinlargepartdirectiveswithtemplates.

    FromanAngular1perspective,Angular2componentshaveassumedalotoftherolesdirectivesusedto.Themajorityofissuesthatinvolvetemplatesanddependencyinjectionruleswillbedonethroughcomponents,andissuesthatinvolvemodifyinggenericbehaviourisdonethroughdirectives.

    TherearethreemaintypesofdirectivesinAngular2:

    Component-directivewithatemplate.Attributedirectives-directivesthatchangethebehaviorofacomponentorelementbutdon'taffectthetemplateStructuraldirectives-directivesthatchangethebehaviorofacomponentorelementbyaffectinghowthetemplateisrendered

    Directives

    91

  • AttributeDirectivesAttributedirectivesareawayofchangingtheappearanceorbehaviorofacomponentoranativeDOMelement.Ideally,adirectiveshouldworkinawaythatiscomponentagnosticandnotboundtoimplementationdetails.

    Forexample,Angular2hasbuilt-inattributedirectivessuchasngClassandngStylethatworkonanycomponentorelement.

    AttributeDirectives

    92

  • NgStyleDirectiveAngular2providesabuilt-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.AlsonoticethatboththehtmlstyleattributeandAngular2ngStyledirectivearecombinedwhenstylingtheelement.

    Wecanremovethestylepropertiesoutofthetemplateintothecomponentasapropertyobject,whichthengetsassignedtoNgStyleusingpropertybinding.Thisallowsdynamicchangestothevaluesaswellasprovidestheflexibilitytoaddandremovestyleproperties.

    NgStyleDirective

    93

    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

    94

  • 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

    95

    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.Angular2applieseachpropertynameofthatobjecttothecomponentifthatpropertyistrue.

    NgClassDirective

    96

    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

    97

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

  • StructuralDirectivesStructuralDirectivesareawayofhandlinghowacomponentorelementrendersthroughtheuseofthetemplatetag.Thisallowsustorunsomecodethatdecideswhatthefinalrenderedoutputwillbe.Angular2hasafewbuilt-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.Angular2alsohasabuilt-intemplatedirectivethatdoesthesamething:

    StructuralDirectives

    98

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

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

    Underastructuraldirective.

    `})

    StructuralDirectives

    99

  • 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

    100

    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

    101

    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

    102

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

  • OftenNgForisusedtoiteratethroughalistofobjectswithauniqueIDfield.Inthiscase,wecanprovideatrackByfunctionwhichhelpsAngularkeeptrackofitemsinthelistsothatitcandetectwhichitemshavebeenaddedorremovedandimproveperformance.

    Angular2willtryandtrackobjectsbyreferencetodeterminewhichitemsshouldbecreatedanddestroyed.However,ifyoureplacethelistwithanewsourceofobjects,perhapsasaresultofanAPIrequest-wecangetsomeextraperformancebytellingAngular2howwewanttokeeptrackofthings.

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

    NgForDirective

    103

  • @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

    104

  • 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

    105

    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

    106

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

  • NgSwitchDirectives

    107

  • UsingMultipleStructuralDirectivesSometimeswe'llwanttocombinemultiplestructuraldirectivestogether,likeiteratingusingngForbutwantingtodoanngIftomakesurethatthevaluematchessomeormultipleconditions.Combiningstructuraldirectivescanleadtounexpectedresultshowever,soAngular2requiresthatatemplatecanonlybeboundtoonedirectiveatatime.Toapplymultipledirectiveswe'llhavetoexpandthesugaredsyntaxornesttemplatetags.

    @Component({selector:'app-root',template:`{{item}}`})

    ViewExample

    TheprevioustabsexamplecanusengForandngSwitchifthetabtitleandcontentisabstractedawayintothecomponentclass.

    UsingMultipleStructuralDirectives

    108

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

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

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

    {{tab.title}}

    {{tab.content}}Selectatab`})exportclassAppComponent{tabNumber:number=-1;

    tabs=[{title:'Tab1',content:'Tabcontent1'},{title:'Tab2',content:'Tabcontent2'},{title:'Tab3',content:'Tabcontent3'},];

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

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

    ViewExample

    UsingMultipleStructuralDirectives

    109

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

  • AdvancedComponents

    Figure:GBNetworkPCICardbyHarkeislicensedunderP