angularjs web application development blueprints related/pdfs and...book, angularjs ui development,...
Post on 26-May-2020
9 Views
Preview:
TRANSCRIPT
-
AngularJSWebApplicationDevelopmentBlueprints
-
TableofContents
AngularJSWebApplicationDevelopmentBlueprints
Credits
AbouttheAuthor
AbouttheReviewers
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmore
Whysubscribe?
FreeaccessforPacktaccountholders
Preface
AboutJavaScriptMVCframeworks
HowAngularJSwasborn
Theideabehindthisbook
Whatthisbookcovers
Whatyouneedforthisbook
Softwareversions
Copyingthecodefiles
Whothisbookisfor
Conventions
Readerfeedback
Customersupport
Downloadingtheexamplecode
Errata
Piracy
Questions
1.IntroductiontoAngularJSandtheSinglePageApplication
DelvingintoSinglePageApps
AnatomyofasimpleAngularJSapp
Modelsandviews
BuildinganAddressBookApp
-
UnderstandingthescopeinAngularJS
Stylingtheapp
Sortingthecontactsalphabetically
AddingcontactstotheAddressBook
Theng-showandng-hidedirectives
Summary
2.SettingUpYourRig
SettingupNode.js
CreatingasimpleNode.jswebserverwithExpressJS
SettingupGrunt
InstallingGrunt-cli
Creatingthepackage.jsonfile
CreatingyourGrunttasks
Grunttaskstomergeandconcatenatefiles
RunningshellcommandsviaGrunt
Yeoman–theworkflowtool
InstallingYeoman
Runningyourapp
UnittestingwithKarma
UsingProtractorforEnd-to-Endtests
InstallingSeleniumServer
Understandingtheexample_spec.jsfile
Understandingtheconf.jsfile
WritingyourownProtractortestcases
Summary
3.RapidPrototypingwithAngularJS
UnderstandingtheapplicationthatwewillPrototype
IntroducingGridLayoutsandBootstrap
Understandingthegridsystem
IntroducingAngularUI
UI-Utils
-
UI-Modules
UI-Bootstrap
NG-Grid
UI-Router
IDEPlugins
PrototypingtheHealthyLivingwebsite
Addingtheui.bootstrapdependency
Creatingthenavigationbar
Addingthecarousel
Tweakingtheherounit
Addingthethreecontentblocks
Creatinganewview
Understandingroutes
Buildingthearticlesview
AccordionsusingAngularBootstrap
Buildingtheimagegallery
GalleryviewusingBootstrapThumbnail
Addingthestarrating
BuildingdatagridsusingNG-Grid
AddingtheNG-Gridcomponent
GroupingdatainNG-Grid
Excel-styleeditinginNG-Grid
Creatingamodalwindowtoaddsubscribers
Real-timeformvalidations
Summary
4.UsingRESTWebServicesinYourAngularJSApp
UnderstandingtheresponsefromaRESTAPI
TestingaRESTfulwebservice
JumpstartingyourappdevelopmentwithAngularSeed
FilesandfoldersinAngularSeed
AddingBootstraplibraries
-
StartingyourNodewebserver
Mark-upourLayout
Creatingtheroutes
UnderstandingAngularJSservices
Writingyourfirstfactoryservice
DependencyInjection
Codingthepartial
CallingtheRESTwebserviceusing$http
Usingpromiseforasynchronouscalls
DisplayingdatafromtheJSONresponse
Unittestingourapplication
Mocking$httpduringUnittesting
CreatingaPintereststylelayout
Addingactionstothebuttons
Summary
5.FacebookFriends’BirthdayReminderApp
UnderstandingtheFacebookSDK
TheSocialGraph
TheGraphAPI
TheGraphAPIExplorer
CreatingyourFacebookapp
Settingupourproject
Runningyourapplication
DelvingintoAngularJSdirectives
Whatisadirective?
Importanceofnamingconventionsfordirectives
Theanatomyofadirective
Writingourfirstdirective
AddingaFacebooklogin
Addingthefb-rootdivelement
LoadingtheFacebookSDK
-
Understanding$watchand$digest
Whentouse$apply
Gettingtheuser’sfriendlist
Gettingyourfriends’profilepicturesandbirthdays
RequestingadditionalpermissionwithFB.login
Understandingisolatedscope
AddingsomeCSSstyles
Changingtheroutes
Addinginthelogoutlink
Writingautomatedtests
WritingUnittestswithKarma
WritingEnd-to-EndtestsusingProtractor
Summary
6.BuildinganExpenseManagerMobileApp
UnderstandingHTML5WebStorage
localStorage
sessionStorage
BuildingtheExpenseManagerApp
BuildingtheAddExpenseform
Whatis$rootScope?
Understandingthe.runblock
CreatingavalueservicetostoreCategoryList
ValidatingtheAddExpenseform
UsinglocalStoragetosavedata
BuildingabarchartdirectivebasedonD3
Summarizingtheexpensesbycategories
Creatingourbarchartdirective
Makingtheappresponsive
AddingtheCSSmediaquery
ScalingtheD3chartbasedonwindowsize
Addingtouchevents
-
EnablingswipegesturesusingngTouch
AddingpagetransitionsusingngAnimate
LoadingthengAnimatemodule
AddingCSS3transitions
Makingtheappfeellikeanativeapp
Addingtouchicons
Runningtheappinfullscreenmode
Addingadditionalfeatures
Summary
7.BuildingaCMSontheMEANStack
WhytheMEANstack?
GettingstartedwiththeMEANstack
SettingupMongoDB
SettingupExpressJSandMongooseJS
Buildingtheserver-sideapp
CreatingtheMongooseschemas
CreatingCRUDroutes
Addinganewentrytothecollection
Updatingacollection
Deletingacollectionitem
Displayingasinglerecord
Securingyouradminsection
Usingbcrypttoencryptpasswords
Addinganewadminuser
Creatingtherouteforauthenticatinglogin
Creatingthelogoutroute
WritingthesessionCheckmiddleware
IntegratingAngularJSwithanExpressJSproject
GeneratingSEO-friendlyURLsusingHTML5mode
BuildingtheadminsectionforCRUDoperations
Creatingtheroutesfortheadminsection
-
Buildingthefactoryservices
Buildingthecontrollersfortheadminsection
Settinguptheadminpagelayout
Buildingthelistingviewfortheadminsection
SettingupauthenticationinAngularJS
Creatingourloginpage
Buildingacustommoduleforglobalnotification
Buildingandinitializingthemessage.flashmodule
Buildingthemessage.flashfactoryservice
Settingup$broadcasts
Buildingthedirectiveforthemessage.flashmodule
Settingaflashmessage
CreatingourAdd-Editpagecontroller
CreatingourAdd-Editview
WritingacustomfiltertoautogeneratetheURLfield
AddingtheWYSIWYGeditor
SettingupanInterceptortodetectresponses
BuildingthefrontendofourCMS
Buildingournavigationbardirective
Buildingtheadmin-logindirective
Displayingthecontentofapage
Settingthedefaulthomepage
Summary
8.ScalableArchitectureforDeploymentsonAWS
UnderstandingthevariousservicesinAmazonAWS
DelvingintoAWSdeploymentarchitectures
TheEC2server-basedarchitecture
TheServer-lessArchitecture
DeployingourappinaServer-lessArchitectureonAWS
MappingadomaintoS3
MappingtheS3buckettoaCloudFrontdistribution
-
Gettingyourappreadyforproductiondeployment
Improvingthepage-loadtimeofyourapp
SettingExpiresheaders
Performance
Summary
9.BuildinganE-CommerceStore
BackendasaService
BuildingaBaaSplatformonAWS
SettingupanS3Bucketwithpublicreadaccess
SettinguptheCORSpolicyonyourS3bucket
CreatingourDynamoDBtables
CreatingtheIdentityandAccessManagement(IAM)role
Creatingoure-commerceapp
BuildingnestedviewsusingUI-Router
MappingstatestoURL,views,andcontrollers
Prototypingourapplication
Settingupourindex.htmlfile
Creatingthecontrollers
Creatingtheproductpartials
Addinganimationstotheviewtransitions
AddingintheCSStransitioneffects
Creatingourapplication-levelcontroller
AddingaFacebooklogin
IntegratingAWSJSSDKwithourapplication
CreatingtheAWSserviceprovider
BuildingourAddProductspage
SavingdatainDynamoDBtables
Creatingtheviewfortheaddproductform
Buildingthecontrollerfortheaddproductsview
UploadingimagestoS3
Fetchingtheproductslistsforacategory
-
Usingresolvestopreloaddata
Creatingourproductdetailspage
Addingproductstocart
Thecheckoutpage
Savingtheorders
Summary
A.AngularJSResources
Officialresources
RecommendedAngularJSmodules
Boilerplates
Learningresources
GoodfriendswithAngularJS(third-partytoolsandservices)
Coreteammembersandknowledgeablepeopletofollow
Index
-
AngularJSWebApplicationDevelopmentBlueprints
-
AngularJSWebApplicationDevelopmentBlueprintsCopyright©2014PacktPublishing
Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.
Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.
PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.
Firstpublished:August2014
Productionreference:1180814
PublishedbyPacktPublishingLtd.
LiveryPlace
35LiveryStreet
BirminghamB32PB,UK.
ISBN978-1-78328-561-7
www.packtpub.com
CoverimagebyFaizFattohi()
http://www.packtpub.commailto:faizfattohi@gmail.com
-
CreditsAuthor
VinciRufus
Reviewers
JeffCunningham
AshutoshDas
AJKerrigan
CiroNunes
YacineRezgui
CommissioningEditor
AkramHussain
AcquisitionEditor
RichardHarvey
ContentDevelopmentEditor
VaibhavPawar
TechnicalEditors
ShashankDesai
MenzaMathew
CopyEditors
KarunaNarayanan
AlfidaPaiva
LaxmiSubramanian
ProjectCoordinators
BinnyK.Babu
KrantiBerde
Proofreaders
BridgetBraund
PaulHindle
LucyRowland
Indexers
HemanginiBari
-
MariammalChettiyar
RekhaNair
PriyaSubramani
Graphics
ValentinaD’silva
ProductionCoordinator
AparnaBhagat
CoverWork
AparnaBhagat
-
AbouttheAuthorVinciRufushasbeenworkingwithfrontendtechnologiesforcloseto14yearsnow.HestartedhiscareerbuildinggameswithFlashActionScriptandlatermovedontoJavaScriptandHTML5.Duringhissparetime,heenjoysconductingworkshopsandtrainingpeople.
Foraliving,hementors,guides,andhelpsgrowthetechnologyteamatRazorfishNeev,primarilyintheareaofcommerce,usability,andemergingtechnologies.
AsincerethankstotheawesometeamatRazorfishNeev.I’velearnedsomuchworkingwithyouall.
Mydeepestregardstothetechnicalreviewers,JeffCunningham,AshutoshDas,AJKerrigan,CiroNunes,andYacineRezgui,andalsotothecontentdevelopmenteditor,VaibhavPawar,whoseinsightsandfeedbackgreatlyhelpedinaddingthefinishingtouchesforthisbook.
Abigthankyoutomyfamily;mydad,Rufus,wholearnedcomputersonlysothathecouldteachme;mymom,Anne,whohasalwaysencouragedmetotakeupchallengeseverytimeIthoughtitwasn’tpossible;myawesomekids,ShannonandJaden,whosacrificedalotoftheirplaytimesothatIcouldwritethisbook;mywife,Raina,forallthesupportthatwasinstrumentalinthisbookreachingitscompletion;andfinally,mysister,Blaisy,whowasalwaystheretogivefeedbackandcritiquemywork,andwithwhomIcouldbrainstormanddiscussideas.
-
AbouttheReviewersJeffCunninghamisamobileappdeveloperatComdatainNashville,TN.After15yearsofworkinginthefieldofJavawebdevelopment,henowenjoysthechallengesoffrontendandmobiledevelopment.Healsoreviewedthebook,AngularJSDirectives,PacktPublishing,andmaintainsthepopularreponamedAngularJS-LearningonGitHub(https://github.com/jmcunningham/AngularJS-Learning).
AshutoshDas,whohailsfromBangladesh,worksmainlyasabackenddeveloperandhisexperienceincludesworkingwithDjango,Node.js,Laravel,andsoon.HealsolikestoworkwithAngularJS.HespendshissparetimewritingforGitHub.Healsoworksasafreelancerandisapart-timejobholder.Heiscurrentlyintheprocessofreviewingthebook,AngularJSUIDevelopment,PacktPublishing.
AJKerriganisasystemsanalystwithasmallITdepartmentinNewJersey.Histechnicaldutiesandinterestsincludeserveranddatabaseadministration,command-linescripting,andwebdevelopment.
AngularJSWebApplicationDevelopmentBlueprints,PacktPublishing,representsAJ’sfirstexperienceasatechnicalreviewer.
Iwouldliketothankmywife,daughter,anddogfortheirlove,support,andendlesssupplyofhugs.Thankstomyfatheraswell,whoprovidedmewithmyfirstexposuretoprogramming(BASIConthefamilyTI-99/4acomputer).Hehasbeenaconsistentsourceofencouragementandguidance.
CiroNunesisa22-yearoldfrontendengineer,test-firstevangelist,andspecialistinlarge-scalearchitecturesforheavyclient-sideapplications.Atsuchayoungage,hehasbeenresponsibleforthedevelopmentofthebiggeste-commercewebsitesfromLatinAmerica.He’salsotheorganizeroftheAngularJSSPMeetupwhichhasmorethan400members.
Nowadays,he’sworkingonapplicationsforthefinancialmarketthatpushestheboundariesofAngularJS.
Iwanttothankmyfamilyandfriendsfortheirpatience,withmebeingsoabsentlately.IpromisethatI’mgoingtowalkmorewiththedogandspendmoretimewithyouwhomIlove.
YacineRezguiisaFrench-Tunisianwebdeveloper.Hestartedwebdevelopingattheageof12,andsincethen,hasmadehispassionhisjob.He’sspecializedinwebdevelopmentandstronglybelievesthatitisthebestcross-platformenvironment.He’scurrentlytheorganizeroftheLondonPhonegapMeetup.
HeworkedindifferentcompaniessuchasMédiamétrieeStat,TequilaRapido,andGovernorHubasafreelancer.
Iwouldliketothankmyfriends,JamesNocentini,JamesSharp,CédricFerretti,andXavierKressforsupportingmeonmywork,myfamilyforalltheirencouragement,andXuxuforhelpingmetofocus.
https://github.com/jmcunningham/AngularJS-Learning
-
www.PacktPub.com
-
Supportfiles,eBooks,discountoffers,andmoreYoumightwanttovisitwww.PacktPub.comforsupportfilesanddownloadsrelatedtoyourbook.
DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusatformoredetails.
Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.
http://PacktLib.PacktPub.com
DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcanaccess,readandsearchacrossPackt’sentirelibraryofbooks.
http://www.PacktPub.comhttp://www.PacktPub.commailto:service@packtpub.comhttp://www.PacktPub.comhttp://PacktLib.PacktPub.com
-
Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,printandbookmarkcontentOndemandandaccessibleviawebbrowser
-
FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandviewnineentirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.
http://www.PacktPub.com
-
PrefaceThemostannoyingpartofusinganywebsiteorwebapplicationisthetimewewaitforpagestoload.Sure,everybodyisworkingonmakingtheWebfast,butthose2-3secondsthatittakesforaroundtriptotheserverdoesnotstopyoufromopeningmultipletabsandoftenforgettingwhichtabyouoriginallywereon.
TherapidpopularityofJavaScriptframeworksandtechnologiessuchasAJAXclearlyshowthedesperateneedtosavethose1or2,second-roundtripstotheserver,andprovidetheuserswithamoredesktop-likeuserexperience.
-
AboutJavaScriptMVCframeworksTheseJavaScriptframeworksaren’tsomenewrevolutionarytechnologyoranewdiscovery;theyareallstillusingthesameoldfaithfulJavaScript.TheseJavaScriptframeworksmerelyprovidealayerofabstraction(ifImay)oramoreModel-View-Controller-likearchitecture,sothatwecanbemoreproductivewhilebuildingappsanddon’treallyhavetoworryaboutmundanethings.
ThecreditfortherisingpopularityoftheseJavaScriptframeworkswouldgotothissurgeofJavaScript-basedhighlyinteractiveandrichInternetapplicationsthatnowadaysdosomuchmorethanjustdisplayingdatareceivedfromabackendserver.AllofthisispossiblethankstothemoderndaybrowserandtheirJavaScriptenginesthathavebecomefasterandpowerful.
TherehasnearlybeenanexplosionoftheseJavaScriptMVCframeworks,andeveryotherday,weseeanewframeworkbeinglaunched.WhilemostpeopleconsiderBackbone.jsorSproutCoretobeoneofthefirstJavaScriptframeworks,IwouldsayExtJSbySenchahasbeenamongthefirstJavaScriptframeworksandonethatisstillbeingextensivelyusedinthecorporateworldmainlytobuildfinanceapps.WhileBackbone.jsandSproutCorewerelaunchedin2010,Version2.0ofExtJSwaslaunchedtowardstheendof2007.
AngularJStoowaslaunchedsomewherein2010.Aroundthesametime,otherJavaScriptframeworksweresproutingup.However,itisprobablythefastestgrowingframeworkintermsofuseradoption,mainlyduetothe“wow”factorandalsothebackingfromthebigG.
Eachframeworkhasitsownprosandcons,andideallythechoiceoftheframeworkwoulddependonthenatureofyourproject.
Notehttp://www.todomvc.com/isaverynicesitetounderstandandcomparethefunctioningoftheseJavaScriptframeworks.
AngularJSiscurrentlythemostpopularJavaScriptMVCframework.Someofthereasonsforthiswouldbeasfollows:
It’samongthesimplesttolearnItfollowssomeofthebestsoftware-engineeringconcepts,andisidealtobuildlarge,scalableappsIthasarobusttestingframeworktorunUnittestsandEnd-to-Endtests,thusmakingiteasytowriteandrunautomatedtestcasesItalsoallowsforteamstoworkinparallelonasingleapplicationwithoutsteppingovereachother’sworkIthasthefastestgrowingcommunityofadaptors,andtheAngularJSGoogleGroupsandIRCchatsareagreatplacetointeractwithothers
http://www.todomvc.com/
-
HowAngularJSwasbornAngularJSstartedasaninternalGoogleprojectbyMiskoHevery,sometimein2009.Asthestorygoes,Misko’steamwasworkingonaprojectcalledGoogleFeedback;evenaftersixmonthsofdevelopmentandabout17,000linesofcode,theywerestillunhappywiththepaceofdevelopmentandtheinabilitytowriteautomatedtests.That’swhenMiskodecidedtorewritethat.Ittookhimabout3weeksandhemanagedtowritethewholethinginjustabout1,500linesofcode.
That’swhenAngularJSgotsomeseriousattentioninternallyatGoogle,andateamwasputtogethertohelpfurtherdevelopit.Around2010,GoogledecidedtodeclareitasopensourceundertheMITlicense.
-
TheideabehindthisbookTheideabehindwritingthisbookistoshowcasethedifferenttypesofapplicationsthatcanbebuiltonAngularJS.BesidesexplainingAngularJSandhowtowritemodularandtestablecode,thereisafairamountofemphasisonmakingthoseappslookbeautiful.So,bereadyforsomeCSSstuffanddesign-relateddiscussions.
I’vetriedtocoveravarietyofapplicationsrangingfromasimpleaddressbook,anHTML5mobileapp,ane-commercestore,aCMSframework,andalsoideasonhowtodeployappsonAmazonAWS.
-
WhatthisbookcoversThisbookisbrokendownintoninechapters.
Chapter1,IntroductiontoAngularJSandtheSinglePageApplication,talksabouttheconceptofaSinglePageAppandhowtheyaredifferentfromtheregularwebapps.We’llalsolearnaboutthebasicsofAngularJSbybuildingasimpleAddressBookApp.
Chapter2,SettingUpYourRig,talksabouthowhavingtherightsetoftoolscanbeahugeproductivitybooster.ItalsomakesyoufeellikeaprowhenbuildingyourAngularJSapp.ThischapterwilltalkaboutsomeofthetoolssuchasNode.js,ExpressJS,Grunt,Yeoman,andKarma.
Chapter3,RapidPrototypingwithAngularJS,talksabouttheeasewithwhichonecancreateclickableprototypestogetafeelofhowanapplicationwouldlookandfeelbeforeworkingonanybackendcode.
Chapter4,UsingRESTWebServicesinYourAngularJSApp,willshowyouhowtoconsumedatafromthird-partyRESTwebservicesusingfactoriesandthe$httpservice.
Chapter5,FacebookFriends’BirthdayReminderApp,willexplaindirectivesandhowwecancreateourFacebooklogindirective.Wewillalsosetupsomeautomatedteststoensureeverythingisworkingfine.
Chapter6,BuildinganExpenseManagerMobileApp,willwalkyouthroughtheprocessofbuildingaresponsiveandtouch-friendlymobileappusingngAnimateandHTML5featuressuchaslocalStorage.
Chapter7,BuildingaCMSontheMEANStack,talksabouthowtosetupanentirebackendandfrontendsystemandhowAngularJSinteractswithanodeserverandMongoDBdatabase.Wewillalsolookatsessionmanagementandinterceptors.
Chapter8,ScalableArchitectureforDeploymentsonAWS,willteachyouaboutAWSanditsvariousservices,andhowwecandeployourappinaServer-lessArchitecturethatcaninherentlyscale.
Chapter9,BuildinganE-CommerceStore,willshowyouhowtodirectlyreadandwritedatafromAWS’sDynamoDBdatabase,anduploadimagestoS3directlyfromourJavaScriptapp.
Appendix,AngularJSResources.Well,youknowwhattoexpecthere.
-
WhatyouneedforthisbookYouobviouslydon’tneedtoreadtheentirebookbeforeyoucanstartworkingonyourfirstAngularJSproject.I’mafirmbelieveroflearningthingsthepracticalway,andthat’swhyfromtheveryfirstchapter,youwillfindyourselffiringupyourIDE/Texteditor,andwritingcodeandtestingitonyourbrowser.
WhileyouwilllearnacoupleofnewfeaturesofAngularJSineachofthechapters,eachchapterisstillself-contained,andyoucancomfortablyjumptoanyofthechaptersthatinterestyouorthatyouneedtorefertoforyourproject.
However,ifyouarejuststartingoffwithAngularJS,thenIstronglyrecommendthatyoureadthroughthefirstthreechaptersbeforeyoustartjumping.
-
SoftwareversionsThecurrentstableversionofAngularJSwhilewritingthisbookis1.2,andunlessspecified,wewillbeusingthestableversionof1.2.17foralltheexamplesinthisbook.
YoucangetthelatestversionofAngularJSusinganyofthefollowingmethods:
Downloadthecompiledminifiedversionfromhttp://www.angularjs.org.ForkorclonethesourcecodefromtheGitHubURLhttps://github.com/angular/angular.js.TherecommendedoptionforbothdevelopmentandproductioncodeistocalltheAngularJSfiledirectlyfromtheGoogleCDN.ThelinktotheAngularJSsectionontheCDNishttps://developers.google.com/speed/libraries/devguide#angularjs.
http://www.angularjs.orghttps://github.com/angular/angular.jshttps://developers.google.com/speed/libraries/devguide#angularjs
-
CopyingthecodefilesThecodeexamplesmentionedinthisbookcanbeusedinyourprograms.However,ifyouchoosetoburnthemontoCDsforredistributionorareputtingupthecodeexamplesfordownloads,youarerequiredtogetexplicitpermissionfromPacktPublishing.
-
WhothisbookisforThisbookismainlyaimedatprofessionals,bothdesignersandprogrammers.Thankfully,AngularJSisevolvingtobeaframeworkwherebothdesignersandprogrammersworktogetherwithoutdiscriminatingeachotherasbackenddevelopersorfrontenddesigners.
ThebookobviouslyassumesthatyouknowyourbasicsinHTML,CSS,andJavaScript.Youunderstandtheimportanceandneedforwritingmodular,scalable,testable,andgood-lookingapplications.Youdon’tneedtohaveworkedwithAngularJSoranyotherJavaScriptframeworktounderstandthetopicscovered.ThebookassumesyoujustmetAngularJSonablinddate.
ThebookstartsoffwithgettingyoucomfortablewiththebasicconceptsthatyoucomeacrossveryoftenwhileworkingwithAngularJS.We’llwritesomesimplecodejusttoseehowAngularJSworks,understandingitbetter,andthenwe’llgraduatetowritingcleanerandmodularcode.
Also,Ihaveachapterdedicatedtosettingupyourdevelopment“rig”withasetoftoolsandpluginsthatwillhelpyouboostyourproductivitywhilebuildingAngularJSapps.
-
ConventionsInthisbook,youwillfindanumberofstylesoftextthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestyles,andanexplanationoftheirmeaning.
Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“Now,angular-bootstrapwillbeavailableforuseacrossourapplication.”
Ablockofcodeissetasfollows:
Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:
{{myName}}is{{2014-1968}}yearsold.
Anycommand-lineinputoroutputiswrittenasfollows:
yoangular:routesubscribers
Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,inmenusordialogboxesforexample,appearinthetextlikethis:“ClickontheDownloadbuttonandselectthefollowingoptionsfromthepop-upwindow:”
NoteWarningsorimportantnotesappearinaboxlikethis.
TipTipsandtricksappearlikethis.
-
ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedormayhavedisliked.Readerfeedbackisimportantforustodeveloptitlesthatyoureallygetthemostoutof.
Tosendusgeneralfeedback,simplysendane-mailto,andmentionthebooktitleviathesubjectofyourmessage.
Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideonwww.packtpub.com/authors.
mailto:feedback@packtpub.comhttp://www.packtpub.com/authors
-
CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.
-
DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesforallPacktbooksyouhavepurchasedfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
http://www.packtpub.comhttp://www.packtpub.com/support
-
ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyouwouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheerratasubmissionformlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedonourwebsite,oraddedtoanylistofexistingerrata,undertheErratasectionofthattitle.Anyexistingerratacanbeviewedbyselectingyourtitlefromhttp://www.packtpub.com/support.
http://www.packtpub.com/submit-erratahttp://www.packtpub.com/support
-
PiracyPiracyofcopyrightmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.Ifyoucomeacrossanyillegalcopiesofourworks,inanyform,ontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.
Pleasecontactusatwithalinktothesuspectedpiratedmaterial.
Weappreciateyourhelpinprotectingourauthors,andourabilitytobringyouvaluablecontent.
mailto:copyright@packtpub.com
-
QuestionsYoucancontactusatifyouarehavingaproblemwithanyaspectofthebook,andwewilldoourbesttoaddressit.
mailto:questions@packtpub.com
-
Chapter1.IntroductiontoAngularJSandtheSinglePageApplicationInthischapter,we’lllearnwhatSinglePageAppsareandhowtheydifferfromtheregularwebapplications.WewillalsolearnthefundamentalsofAngularJSandgoaboutbuildingasimpleAddressBookAppusingit.
Thelistoftopicstobecoveredinthechapterareasfollows:
WhatareSinglePageApps?AnatomyofanappModelsandviewsBuildinganAddressBookAppStylingtheappwithCSSAddingitemstotheAddressBook
-
DelvingintoSinglePageAppsBesidesotherthings,AngularJSisprimarilyusedtobuildSinglePageApps(SPAs),soletusfirstunderstanditscharacteristics.
SinglePageAppsareappsorwebsiteswhereintheentiresiteorappcontentloadswithinasinglepage.Thisessentiallymeansthatoncetheapporwebsiteisloadedinthebrowser,clickingonanylinkwouldnotreloadtheentirepagebutwouldsimplyupdatecertainsectionswithinthemainpageitself.Thisgivesusersaverydesktop-likefeelwhileusinganSPA.
AlthoughSPAshavebecomeverypopularnowadays,theconcepthasbeendiscussedasearlyas2003,andthetermSinglePageAppwascoinedin2005.
SomeofthetechnologiesthatplayapredominantroleinbuildingSPAsareHTML,CSS,JavaScript,AJAX,andwebservicesusuallyRESTful.Ofthese,JavaScriptplaysthemostcrucialroleinbuildinganSPA,soifyouhavebeenprocrastinatingonsharpeningyourJavaScriptskillsthiswouldbethebesttimetogetupandgetstarted.
OneofthefundamentaldifferencesinthewaySPAsworkagainstregularwebsitesisthewaythepagesarebuilt,whichtheusersees.Refertothefollowingdiagram:
-
Intraditionalwebapplicationsthatarebuiltontheserver-sidetechnologiessuchasJava,PHP,and.NET,wheneverapageisrequested,thewebserverwouldmakearequesttothedatabase,fetchtheresultofthequery,thenloadthetemplate,anddynamicallygeneratethefinalpage,whichissentdowntothebrowser.Asyoucanseehere,thewebserverisdoingalltheheavylifting,andasthetraffictotheserverincreases,thewebserverbecomesabottleneck.Thisiswhypopularhigh-trafficsitesneedalotofservers.
SinglePageApps,especiallythosebuiltonJavaScriptframeworkssuchasAngularJSworkinaslightlydifferentfashion.Refertothefollowingdiagram:
InanSPAarchitecture,theentiretemplatealongwiththeHTML,JavaScript,andCSSisdownloadedtotheuser’sbrowser,sowhenarequestismade,contentissentfromthewebserverandthepageisbuiltontheclientsideontheuser’sbrowser.Here,thebrowserisdoingtheheavylifting.Insuchanarchitecture,thewebserverismerelypassingrawdataandisnotinvolvedinbuildingthepages.Thepagesarebuiltoneachuser’sbrowserandhenceevenifthetraffictothesiteincreases,theserverdoesn’tgetoverloaded,asitwouldhaveinaregularwebapparchitecture.
AnotherthingthatmakesSPAswonderfulisthatthepresentationlayercanbecompletelydecoupledfromthebackendlayer.
-
AnatomyofasimpleAngularJSappPerformthefollowingsteps:
1. Tostart,let’sfirstdownloadaversionofAngularJSfromhttp:www.angularjs.org.2. ClickontheDownloadbuttonandselectthefollowingoptionsfromthepop-up
window:
Branch:SelectStableBuild:SelectMinified
3. DownloadtheJSfileandplaceitinyourproject’sfolder.
LetusstartbywritingasimpleAngularJSapp.Createanindex.htmlfilewiththefollowingcode:
AngularJSBasic
{{myName}}is{{2014-1968}}yearsold.
ThisisaregularHTMLpagewiththeHTML5doctypeandtheAngularJSJavaScriptfilebeingcalledin.Now,letuslookatspecificsyntaxesofAngularJSandwhattheymean.Thesyntaxesareasfollows:
ng-app:ThisdefinestheelementwithinwhichAngularJSwillbootstrapitself.Inmostcases,wewouldaddittotheortag.ItisalsopossibleyouwouldbebuildingaregularapplicationinJava,PHP,or.NETandonlyasectionofitwouldberunninganAngularJSapp,insuchcasesyouwouldaddng-apptothetagwrappingtheappcomponent.ng-init:Thisisusedtodefinetheinitializationtasks.Inthisexample,wearecreatingamodelcalledmyNamewiththevalueJohnDoe.
NoteUsingng-initisnotrecommendedforproductionapps.Aswewillseelaterinthischapter,theidealwaytoinitializethevariablewouldbeinthecontrollerinsteadofdirectlywritingitintheview.
{{}}:Thedoublecurlybracketsareusedtooutputthedatastoredinmodels.Inthiscase,{{myName}}outputsthevalueJohnDoe.Thesecurlybracketscanalsobeusedforexpressions,asintheexample{{2014-1968}}outputstheresult46.ThisisverysimilartohowothertemplatingenginessuchasMustacheorSmartywork.Directives:Theng-appandtheng-inittagsthatyouseeintheprecedingsample
http://www.angularjs.org
-
codearecalledDirectives.TheyareanintegralpartofanyAngularJSappanditisthroughthesedirectivesthatAngularJSisabletomodifytheDOMelementofanapplication.AngularJScomeswithawholesetofpredefineddirectivesmanyofwhichwewilluseaswegothroughthisbook.ThegoodthingaboutAngularJSisthatyoucanalsocreateyourowncustomdirectivesthatcanmeetyourspecificrequirements.
-
ModelsandviewsInAngularJS,amodelcouldbeaprimitive,ahashtable,oraJavaScriptobject.Thedatafromthemodelcanbedisplayedintheviewusingthe{{}}expression.
Modelscanbedefinedinmultipleways.Likewesawinthefirstexample,wecandefinethemodelwithintheng-initdirective.Itcanbecreatedinthetemplatewithintheexpressionasfollows:
click
Alternatively,itcouldalsobecreatedwithinacontrollerusingthescope,whichistheidealwaytodoit.Refertothefollowingcode:
ModelinScope
{{person.name}}livesin{{person.city}}functionPeopleController($scope){$scope.person={name:"JohnDoe",city:"NewYork"}}
Intheprecedingexample,wecreatedacontrollercalledPeopleControlleranddefinedthemodelperson,whichisstoringthedataasahashtable.The$scopeisanAngularJSobjectthatisabletoreferencetheJavaScriptobjectmodelasaproperty.
-
BuildinganAddressBookAppIntheearlierexamples,wesawthedifferentwaysofcreatingmodels.Whencreatingproductiongradeorlarge-scaleapplications,whichinvolvegraphicalinterfaces,itiscompulsorytofollowtheModelViewController(MVC)designpattern.
Buildingonthepreviouscodeexample,we’llgoaheadandbuildasimpleAddressBookApp.
Let’sstartbycreatingourmodelsinacontrollercalledPeopleController.We’llnowwriteallourJavaScriptsinafilecalledscripts.js.Yourscripts.jsfileshouldlooklikethis:
functionPeopleController($scope){$scope.people=[{name:"JohnDoe",phone:"3452345678",city:"NewYork"},{name:"SarahParker",phone:"1236548769",city:"Chicago"},{name:"LittleJohn",phone:"4567853432",city:"LosAngeles"},{name:"AdamDoe",phone:"9025673152",city:"LasVegas"}];}
HerewearedefiningthecontrollercalledPeopleControllerandcreatingourmodelcalledpeople.Themodelcontainsthreeattributes:name,phone,andcity.
Now,letusgetourmarkupinplace.Letuscallthefileindex.htmlusingthefollowingcode:
AddressBookAddressBook{{person.name}}-{{person.phone}}{{person.city}}
TipItisalwaysagoodpracticetoloadyourJSfilesattheendofthepagejustabovethebodytagandnotinthehead.Youcanreadmoreaboutwhythismattershereathttps://developer.yahoo.com/performance/rules.html.
https://developer.yahoo.com/performance/rules.html
-
Asyoucanseehere,wearedefiningtheHTML5doctypeinthefirstline,andthenweinitializetheAngularJSapplicationbyusingtheng-appdirective.You’llalsonoticethatweareusingtheng-controllerdirectiveandassigningPeopleControllertoit.Bydoingso,wearedefiningthesectionoftheDOMthatisnowwithinthescopeofthiscontroller.
You’llalsonoticeanewdirectivecalledng-repeat;thisisthebuilt-indirectiveusedtodisplayalistofitemsfromacollection.Theng-repeatdirectivewouldsimplyduplicatetheDOMelementandbindthedefinedpropertiesofthedataobject.
Asyoucansee,ng-repeatmakesitsoeasyandcleantodisplayrecordsetsascomparedtodoingthisinjQueryorplainvanillaJavaScript.
Now,runyourindex.htmlinthebrowserandyoushouldbeseeingthenameswiththeirphonenumbersandcitiesbeingdisplayed.Thedatafromourmodelisshowingup,whichisgood.LetusalsoinspectthecodetohavealookatthechangesAngularJSismakingtoourmarkup.
Allmodernbrowsersallowyoutoinspectthesource.Andinmostcasesyoucansimplyright-clickonthepageandselectInspectElement.IncaseyouarenotcomfortablewithInspect,youcanalsodoViewSource.Refertothefollowingscreenshot:
-
TipBytheway,hereI’musingFirebug,anawesomeadd-onforMozillaFirefox.
Asyoulookthroughthecode,you’llnoticethatAngularJSismakingafairbitofchangetothemarkup.
Thefirstthingyou’llnoticeisthatAngularJSaddsaclasscalledng-scopetoeveryDOMelementwherethescopeisinitialized(wewillgettowhatascopeis,injustabit).ItduplicatestheentireDOMpresentwithintheng-repeatdirective.Itisalsoaddingaclasscalledng-bindingtoeveryelementwherethedataisbound.
AngularJSwilladddifferentCSSclassesdependingonthedirectivebeingused.Thesecancomeinhandywhenyouwanttostyle,forexample,thevalidationmessageswhileworkingwithforms.We’llseemoreaboutthisinthechaptersahead.
-
UnderstandingthescopeinAngularJSLetusnowlookatthisthingcalledthescope.Asyoumighthavenoticed,wedefinedourpeoplecontrollerwitha$scopeparameter.Wealsohadtodefineourpeoplemodelasapartofthisscope.Whileinspectingtheelements,wealsonoticedmultipleng-scopeclassesbeingdefined.So,whatexactlyisthisscopeandisitreallythatimportant?
AsperAngularJS’sdocuments,thescopeobjectreferstotheapplicationmodelandprovidesanexecutioncontextfortheexpressionsintheviews.
Theexpression{{person.name}}isabletodisplaythecontentonlybecausethenameisapropertythatcanbeaccessedbythescope.
AnotherimportantthingtonoteisthateveryAngularJSappwillhavearootscopecreatedattheng-appdirective.Manyotherdirectivescouldalsocreatetheirownscope.ScopesarearrangedinahierarchicalfashionfollowingtheDOMstructureofthepage.ChildScopesprototypicallyinheritfromtheirparentscope.
Theexceptiontothisisincaseswhereadirectiveusesascopeoption,itcreatesanisolatedscope.MoreinformationaboutthedirectivesandisolatedscopeisavailableinChapter5,FacebookFriends’BirthdayReminderApp.
We’llgetabetterunderstandingofitasweseeotherexamples.
-
StylingtheappNow,letusstyletheapplicationtomakeitlookalittlebetter.We’llgobacktoourindex.htmlandaddafewCSSclassesasfollows:
AddressBook
AddressBook
-
padding:10px;
}.contact-item{border-bottom:thinsolid#ccc;padding:10px;}
AsyoucanseefromtheCSSstyles,wefirststylethebodytogiveitalightgraybackgroundcolorusingthe#ccc(#cccistheshortcodefor#cccccc)hexcode.
TheH1headingtagisstyledtoaligncenter,withadarkgraytextcolorandatextshadow.Thestylingfor.nameand.cityisstraightforward.Now,letuslookatthestylesfor.wrapperusingthefollowingcode:
.wrapper{width:650px;margin:0auto;box-shadow:5px5px5px#555;background:#fff;border-radius:15px;padding:10px;
}
Here,wearesettingwidthofthedivto650px.Themarginwith0autoisusedtoplacethedivtothecenterofthescreenirrespectiveofthescreenresolution.
TipDownloadingtheexamplecode
YoucandownloadtheexamplecodefilesforallPacktbooksyouhavepurchasedfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
Nowtomakeitlookalittlebetter,we’llgiveitabox-shadowandborderradius.Thefollowingdiagramexplainswhattheoptionsoftheborderradiusmean:
Forthe.contact-itemlist,wegiveaborder-bottomandsomepaddingsothatthingsstayalittlespacedout.
http://www.packtpub.comhttp://www.packtpub.com/support
-
WithallthisCSSinplace,yourappshouldbelookinglikethis:
-
SortingthecontactsalphabeticallyThislooksnice,butitwouldbeagoodideatohavethenamessortedalphabetically.Forthis,wewilluseAngularJS’sbuilt-infiltercalledorderBy.
InAngularJS,filtersareusedtoformatthedata.OnecanuseAngularJS’spredefinedfiltersorcreateyourown.We’lllearnmoreaboutfilterslaterinthisbook.
Allweneedtodoismodifythefollowingsectionoftheindex.htmlasfollows:
{{person.name}}-{{person.phone}}{{person.city}}
RefreshyourIndex.htmlinthebrowserandyoushouldnoticethenamesarenowsortedalphabetically.
-
AddingcontactstotheAddressBookNowthatwehaveourAddressBookdisplayingourcontactsnicely,let’snowcreateaformtoaddcontacts.
LetusaddthemarkupfortheAddaContactformintheindex.htmlfilewithinthebodytagasfollows:
AddaContactName:Phone:City:Save
Theprecedingcodeisratherstraightforward.Wecreateanewdivandreusethewrapperclasstostyleit.
Weareaddingthethreetextboxesforthename,phone,andcityattributes.WebindthesethreetextboxestoamodelobjectcallednewPersonasfollows:
ng-model='newPerson.name'ng-model='newPerson.phone'ng-model='newPerson.city’
WearealsoaddingabuttoncalledSaveandusingtheng-clickdirectivethatwillcalltheSave()functionwhenthebuttonisclicked.
Now,letuslookattheJavaScriptcodethatwewillbewritinginourscripts.jsfile:
$scope.Save=function(){$scope.people.push({name:$scope.newPerson.name,phone:$scope.newPerson.phone,city:$scope.newPerson.city});}
TipSincetheSave()functionisaccessingthescopewithinthePeopleControllerfunction,itisimperativethattheSave()functioniswrittenwithinthePeopleControllerfunctioninthescripts.jsfile.
Inthe$scope.Savefunction,wesimplycapturethevaluesfromtheinputboxesandpushthisintoourmainpeoplemodel.
Letusnowrefreshourindex.htmlandtryitout.FilluptheformandsaveitandyouwillimmediatelyseeitgetaddedtotheAddressBook.ThishappensthankstooneofthemanycoolfeaturesofAngularJScalledtwo-waydatabinding.
-
Theng-showandng-hidedirectivesWhiletheappisgoodasitis,maybeit’sagoodideatohaveabuttoncalledAddContactanddisplaytheAddContactformonlywhenthatbuttonisclicked.
LetusmakeuseofAngularJS’sng-showandng-hidedirectivestocontrolthevisibilityofourAddContactform.
Thewaytheyworkisverystraightforward.Iftheattributeng-show='true',thenthedivisvisibleandviceversa.Apointtonoteisthatng-showandng-hidemerelycontrolthevisibilityoftheDOMelement.
Let’saddourbuttoncalledAddContactandsetuptheng-showandng-hidedirectivessuchthatwhenyouclickonAddContact,theformshowsupandatthesametimethisbuttondisappears.AndwhentheSavebuttonisclicked,theformishiddenandtheAddContactbuttonshowsupagain.
Let’smodifyourindex.htmlasfollows:
AddContactAddaContactName:Phone:City:Save
Wesetthebuttontong-hide='formVisibility'becausewhenthevalueofformVisibilitybecomestrue,itwillhidethebutton.Similarly,ng-show=formVisibilitywillmaketheAddContactformdisplaywhenthevalueofformVisibilityistrue.
Now,let’saddthepieceofJavaScripttosettheformVisibilityvalues.Addthefollowingcodetoyourscripts.jsfileasfollows:
$scope.ShowForm=function(){$scope.formVisibility=true;}
TipMakesurethisnewfunctioniswrittenwithinthemainPeopleControllerfunction.
Wewillalsoaddonelineinourexisting$scope.SavefunctiontosetthevalueofformVisibilitytofalse.
Pleaseupdatethe$scope.Save()functionashighlightedinthefollowingcode:
$scope.Save=function(){
$scope.people.push({name:$scope.newPerson.name,
-
phone:$scope.newPerson.phone,city:$scope.newPerson.city});$scope.formVisibility=false;
}
Reloadyourindex.htmlandseethebuttonsinaction.
Ohandjustbecausewedon’tlikethewaythosedefaultbuttonslook,letsaddalittlebitofstyletoit.
AddthefollowingCSSclassestoyourstyles.cssfile:
button{background:#080;color:#fff;padding:5px15px;border-radius:5px;border:thinsolid#060;"margin:5pxauto;"}button:hover{background:#0A0;}
Whatwearesimplydoinghereissettingadarkgreencolorbackgroundforthebutton,givingthetextawhitecolor,andgivingitsomepaddingfivepixelsfromthetop-andbottom-sideand15pixelsfromtheleft-handsideandright-handsideandaddingsomeborderradius.
Thebutton:hoverisalightgreenbackgroundcolorjusttoshowthehighlightwhentheuserhoversthecursoroverthebutton.
Reloadyourindex.htmlpageandwehaveourveryfirstworkingandreasonablygood-lookingAddressBookApplication.
-
SummaryThisconcludesourfirstchapter.Toquicklysummarize,wewentaboutbuildingourAddressBookAppandindoingsolearnedaboutthevariousAngularJSdirectivessuchasng-appandng-repeat.Wesawhowtwo-waydatabindingsandexpressionsworkandtheimportanceofscope.Wealsosawhowwecanhideandshowcertainelementsusingtheng-showandng-hidedirectives.Lastbutnotleast,weusedsomesimpleandeasyCSS3featurestostyleourapp.
Inthenextchapter,wewillseethevarioustoolsthatfrontenddevelopersshouldideallyhaveintheirtoolboxandhowtogoaboutusingthem.
-
Chapter2.SettingUpYourRigI’msureyouwouldhaveheardthesaying,“Atoolmanisknownbythetoolshekeeps.”OKfine,Ijustmadethatup,butthat’sactuallytrue,especiallywhenitcomestoprogramming.SureyoucanbuildcompleteandfullyfunctionalAngularJSappsjustusingasimpletexteditorandabrowser,butifyouwanttoworklikeaninja,thenmakesurethatyoustartusingsomeofthesetoolsasapartofyourdevelopmentworkflow.
DonotethatthesetoolsarenotmandatorytobuildAngularJSapps.Theiruseisrecommendedmainlytohelpimprovetheproductivity.
Inthischapter,wewillseehowtosetupandusethefollowingproductivitytools:
Node.jsGruntYeomanKarmaProtractor
SincemostofusarerunningaMac,Windows,Ubuntu,oranotherflavoroftheLinuxoperatingsystem,we’llbecoveringthedeploymentstepscommonforallofthem.
-
SettingupNode.jsDependingonyourtechnologystack,IstronglyrecommendyouhaveeitherRubyorNode.jsinstalled.
IncaseofAngularJS,mostoftheproductivitytoolsorpluginsareavailableasNodePackageManager(npm),and,hence,wewillbesettingupNode.jsalongwithnpm.Node.jsisanopensourceJavaScript-basedplatformthatusesanevent-basedInput/outputmodel,makingitlightweightandfast.
Letusheadovertowww.nodejs.organdinstallNode.js.Choosetherightversionasperyouroperatingsystem.
ThecurrentversionofNode.jsatthetimeofwritingthisbookisv0.10.xwhichcomeswithnpmbuiltin,makingitabreezetosetupNode.jsandnpm.
TipNode.jsdoesn’tcomewithaGraphicalUserInterface(GUI),sotouseNode.js,youwillneedtoopenupyourterminalandstartfiringsomecommands.NowwouldalsobeagoodtimetobrushuponyourDOSandUnix/Linuxcommands.
AfterinstallingNode.js,thefirstthingyou’dwanttocheckistoseeifNode.jshasbeeninstalledcorrectly.
So,letusopenuptheterminalandwritethefollowingcommand:
node–-version
ThisshouldoutputtheversionnumberofNode.jsthat’sinstalledonyoursystem.Thenextwouldbetoseewhatversionofnpmwehaveinstalled.Thecommandforthatwouldbeasfollows:
npm–-version
Thiswilltellyoutheversionnumberforyournpm.
http://www.nodejs.org
-
CreatingasimpleNode.jswebserverwithExpressJSForbasic,simpleAngularJSapps,youdon’treallyneedawebserver.YoucansimplyopentheHTMLfilesfromyourfilesystemandtheywouldworkjustfine.However,asyoustartbuildingcomplexapplicationswhereyouarepassingdatainJSON,webservices,orusingaContentDeliveryNetwork(CDN),youwouldfindtheneedtouseawebserver.
ThegoodthingaboutAngularJSappsisthattheycouldworkwithinanywebserver,soifyoualreadyhaveIIS,Apache,Nginx,oranyotherwebserverrunningonyourdevelopmentenvironment,youcansimplyrunyourAngularJSprojectfromwithinthewebrootfolder.
Incaseyoudon’thaveawebserverandarelookingforalightweightwebserver,thenletussetoneupusingNode.jsandExpressJS.
OnecouldwritetheentirewebserverinpureNode.js;however,ExpressJSprovidesanicelayerofabstractionontopofNode.jssothatyoucanjustworkwiththeExpressJSAPIsanddon’thavetoworryaboutthelow-levelcalls.
So,let’sfirstinstalltheExpressJSmoduleforNode.js.
Openupyourterminalandfirethefollowingcommand:
npminstall-gexpress-generator
ThiswillgloballyinstallExpressJS.Omitthe–gtoinstallExpressJSlocallyinthecurrentfolder.
WheninstallingExpressJSgloballyonLinuxorMac,youwillneedtorunitviasudoasfollows:
sudonpminstall–gexpress-generator
Thiswillletnpmhavethenecessarypermissionstowritetotheprotectedlocalfolderundertheuser.ThenextstepistocreateanExpressJSapp;letuscallitmy-server.Typethefollowingcommandintheterminalandhitenter:
expressmy-server
You’llseesomethinglikethis:
create:my-servercreate:my-server/package.jsoncreate:my-server/app.jscreate:my-server/publiccreate:my-server/public/javascriptscreate:my-server/public/imagescreate:my-server/public/stylesheetscreate:my-server/public/stylesheets/style.csscreate:my-server/routescreate:my-server/routes/index.js
-
create:my-server/routes/user.jscreate:my-server/viewscreate:my-server/views/layout.jadecreate:my-server/views/index.jade
installdependencies:$cdmy-server&&npminstall
runtheapp:$DEBUG=my-server./bin/www
Thiswillcreateafoldercalledmy-serverandputinabunchoffilesinsidethefolder.
NoteThepackage.jsonfileiscreated,whichcontainstheskeletonofyourapp.Openitandensurethenamesaysmy-server;also,notethedependencieslisted.
Now,toinstallExpressJSalongwiththedependencies,firstchangeintothemy-serverdirectoryandrunthefollowingcommandintheterminal:
cdmy-servernpminstall
Now,intheterminal,typeinthefollowingcommand:
npmstart
Openyourbrowserandtypehttp://localhost:3000intheaddressbar.You’llgetaniceExpressJSwelcomemessage.NowtotestourAddressBookAppcreatedinChapter1,IntroductiontoAngularJSandtheSinglePageApplication,wewillcopyourindex.html,scripts.js,andstyles.cssintothepublicfolderlocatedwithinmy-server.
NoteI’mnotcopyingtheangular.jsfilebecausewe’llusetheCDNversionoftheAngularJSlibrary.
Openuptheindex.htmlfileandreplacethefollowingcode:
WiththeCDNversionofAngularJSasfollows:
Aquestionmightarise,astowhatiftheCDNisunreachable.Insuchcases,wecanaddafallbacktousealocalversionoftheAngularJSlibrary.
WedothisbyaddingthefollowingscriptaftertheCDNlinkiscalled:
window.angular||document.write('');
Savethefileinthebrowserandenterlocalhost:3000/index.html.YourAddressBook
-
isnowrunningfromaserverandtakingadvantageofGoogle’sCDNtoservetheAngularJSfile.
TipReferencingthefilesusingonly//isalsocalledtheprotocolindependentabsolutepath.Thismeansthatthefilesarerequestedusingthesameprotocolthatisbeingusedtocalltheparentpage.Forexample,ifthepageyouareloadingisviahttps://,thentheCDNlinkwillalsobecalledviaHTTPS.
Thisalsomeansthatwhenusing//insteadofhttp://duringdevelopment,youwillneedtorunyourappfromwithinaserverinsteadofafilesystem.
-
SettingupGruntGruntisaJavaScript-basedtaskrunner.Itisprimarilyusedforautomatingtaskssuchasrunningunittests,concatenating,merging,andminifyingJSandCSSfiles.Youcanalsorunshellcommands.Thismakesitsupereasytoperformservercleanupsanddeploycode.Essentially,GruntistoJavaScriptwhatRakewouldbetoRubyorAnt/MavenwouldbetoJava.
-
InstallingGrunt-cliInstallingGrunt-cliisslightlydifferentfrominstallingotherNode.jsmodules.WefirstneedtoinstalltheGrunt’sCommandLineInterface(CLI)byfiringthefollowingcommandintheterminal:
npminstall-ggrunt-cli
MacorLinuxuserscanalsodirectlyrunthefollowingcommand:
sudonpminstall–ggrunt-cli
Makesureyouhaveadministrativeprivileges.UsesudoifyouareonaMacorLinuxsystem.IfyouareonWindows,right-clickandopenthecommandpromptwithadministrativerights.AnimportantthingtonoteisthatinstallingGrunt-clidoesn’tautomaticallyinstallGruntanditsdependencies.
Grunt-climerelyinvokestheversionofGruntinstalledalongwiththeGruntfile.Whilethismayseemalittlecomplicatedatstart,thereasonitworksthiswayissothatwecanrundifferentversionsofGruntfromthesamemachine.ThiscomesinhandywhenyourprojecthasdependenciesonaspecificversionofGrunt.
-
Creatingthepackage.jsonfileToinstallGruntfirst,let’screateafoldercalledmy-projectandcreateafilecalledpackage.jsonwiththefollowingcontent:
{"name":"My-Project","version":"0.1.0","devDependencies":{"grunt":"~0.4.5","grunt-contrib-jshint":"~0.10.0","grunt-contrib-concat":"~0.4.0","grunt-contrib-uglify":"~0.5.0","grunt-shell":"~0.7.0"
}}
Savethefile.Thepackage.jsoniswhereyoudefinethevariousparametersofyourapp;forexample,thenameofyourapp,theversionnumber,andthelistofdependenciesneededfortheapp.
HerewearecallingourappMy-ProjectwithVersion0.1.0,andlistingoutthefollowingdependenciesthatneedtobeinstalledasapartofthisapp:
grunt(v0.4.5):ThisisthemainGruntapplicationgrunt-contrib-jshint(v0.10.0):Thisisusedforcodeanalysisgrunt-contrib-concat(v0.4.0):Thisisusedtomergetwoormorefilesintoonegrunt-contrib-uglify(v0.5.0):ThisisusedtominifytheJSfilegrunt-shell(v0.7.0):ThisistheGruntshellusedforrunningshellcommands
Visithttp://gruntjs.com/pluginstogetalistofallthepluginsavailableforGruntandalsotheirexactnamesandversionnumbers.
NoteYoumayalsochoosetocreateadefaultpackage.jsonfilebyrunningthefollowingcommandandansweringthequestions:
npminit
Openthepackage.jsonfileandaddthedependenciesasmentionedearlier.
Nowthatwehavethepackage.jsonfile,loadtheterminalandnavigateintothemy-projectfolder.ToinstallGruntandthemodulesspecifiedinthefile,typeinthefollowingcommand:
npminstall--save-dev
You’llseeaseriesoflinesgettingprintedintheconsole,letthatcontinueforawhileandwaituntilitreturnstothecommandprompt.EnsurethatthelastlineprintedbythepreviouscommandendswithOKcode0.
OnceGruntisinstalled,aquickversioncheckcommandwillensurethatGruntis
http://gruntjs.com/plugins
-
installed.Thecommandisasfollows:
grunt–-version
Thereisapossibilitythatyougotabunchoferrorsanditendedwithanotokcode0message.Therecouldbemultiplereasonswhythatwouldhavehappened,rangingfromerrorsinyourcodetoanetworkconnectionissueorsomethingchangingatGrunt’sendduetoanewversionupdate.
Ifgrunt--versionthrowsupanerror,itmeansGruntwasn’tinstalledproperly.ToreinstallGrunt,enterthefollowingcommandsintheterminal:
rm–rfnode_modulesnpmcachecleannpminstall
Windowsusersmaymanuallydeletethenode_modulesfolderfromWindowsExplorer,beforerunningthecachecleancommandinthecommandprompt.
TipRefertohttp://www.gruntjs.comtotroubleshoottheproblem.
http://www.gruntjs.com
-
CreatingyourGrunttasksTorunourGrunttasks,we’llneedaJavaScriptfile.So,let’scopyourscritps.jsfromthepreviouschapterandplaceitintothemy-projectsfolder.
ThenextstepistocreateaGruntfilethatwilllistoutthetasksthatweneedGrunttoperform.
Fornow,wewillaskittodofoursimpletasks,firstcheckifourJScodeiscleanusingJSHint,thenwewillmergethreeJSfilesintooneandthenminifytheJSfile,andfinallywewillrunsomeshellcommandstocleanup.
NoteUntilVersion0.3,theinitcommandwasapartoftheGrunttoolandonecouldcreateablankprojectusinggrunt-init.WithVersion0.4,initisnowavailableasaseparatetoolcalledgrunt-initandneedstobeinstalledusingthenpminstall–ggrunt-initcommandline.Alsonotethatthestructureofthegrunt.jsfilefromVersion0.4onwardsisfairlydifferentfromtheearlierversionsyou’veused.
Fornow,wewillresorttocreatingtheGruntfilemanually.Refertothefollowingscreenshot:
Inthesamelocationaswhereyouhaveyourpackage.json,createafilecalledgruntfile.jsasshownearlierandtypeinthefollowingcode:
module.exports=function(grunt){//Projectconfiguration.grunt.initConfig({jshint:{all:['scripts.js']}});
grunt.loadNpmTasks('grunt-contrib-jshint');
-
//Defaulttask.grunt.registerTask('default',['jshint']);};
Tostart,wewilladdonlyonetaskwhichisjshintandspecifyscripts.jsinthelistoffilesthatneedtobelinted.Inthenextline,wespecifygrunt-contrib-jshintasthenpmtaskthatneedstobeloaded.Inthelastline,wedefinethejshintasthetasktoberunwhenGruntisrunningindefaultmode.Savethefileandintheterminalrunthefollowingcommand:
grunt
Youwouldprobablygettoseethefollowingmessageintheterminal:
SoJSHintissayingthatwearemissingasemicolononlines18and24.Oh!DidImentionthatJSHintislikeyourverystrictmathteacherfromhighschool.
Let’sopenupscripts.jsandputinthosesemicolonsandrerunGrunt.Nowyoushouldgetamessageingreensaying1filelintfree.Donewithouterrors.
Let’saddsomemoretaskstoGrunt.We’llnowaskittoconcatenateandminifyacoupleofJSfiles.Sincewecurrentlyhavejustonefile,let’sgoandcreatetwodummyJSfilescalledscripts1.jsandscripts2.js.
Inscripts1.jswe’llsimplywriteanemptyfunctionasfollows:
//Thisisfromscript1functionScript1Function(){//------//}
Similarly,inscripts2.jswe’llwritethefollowing:
//Thisisfromscript2functionScript2Function(){//------//}
Savethesefilesinthesamefolderwhereyouhavescripts.js.
-
GrunttaskstomergeandconcatenatefilesNow,let’sopenourGruntfileandaddthecodeforboththetasks—tomergetheJSfile,andminifythemasfollows:
module.exports=function(grunt){//Projectconfiguration.grunt.initConfig({jshint:{all:['scripts.js']},concat:{dist:{src:['scripts.js','scripts1.js','scripts2.js'],dest:'merged.js'}},
uglify:{dist:{src:'merged.js',dest:'build/merged.min.js'}}});
grunt.loadNpmTasks('grunt-contrib-jshint');grunt.loadNpmTasks('grunt-contrib-concat');grunt.loadNpmTasks('grunt-contrib-uglify');
//Defaulttask.grunt.registerTask('default',['jshint','concat','uglify']);};
Asyoucanseefromtheprecedingcode,afterthejshinttask,weaddedtheconcattask.Underthesrcattribute,wedefinethefilesseparatedbyacommathatneedtobeconcatenated.Andinthedestattribute,wespecifythenameofthemergedJSfile.
TipItisveryimportantthatthefilesareenteredinthesamesequenceastheyneedtobemerged.Ifthesequenceofthefilesenteredisincorrect,themergedJSfilewillcauseerrorsinyourapp.
TheuglifytaskisusedtominifytheJSfileandthestructureisverysimilartotheconcattask.Weaddthemerged.jsfiletothesrcattributeandinthedestattribute,wewillplacethemerged.min.jsfileintoafoldercalledbuild.
Note
-
Gruntwillautocreatethebuildfolder.
Afterdefiningthetasks,wewillloadthenecessaryplugins,namelythegrunt-contrib-concatandthegrunt-contrib-uglify,andfinallywewillregistertheconcatanduglifytaskstothedefaulttask.
SavethefileandrunGrunt.Andifallgoeswell,youshouldseeGruntrunningthesetasksandinformingthestatusofeachofthetasks.
Ifyougetthefinalmessagesaying,Done,withoutanyerrors,itmeansthingswentwell,andthiswasyourluckyday!
Ifyounowopenyourmy-projectfolderinthefilemanager,youshouldseeanewfilecalledmerged.js.Openitinthetexteditorandyou’llnoticethatallthethreefileshavebeenmergedintothis.Also,gointothebuild/merged.min.jsfileandverifywhetherthefileisminified.
-
RunningshellcommandsviaGruntAnotherreallyhelpfulplugininGruntisgrunt-shell.Thisallowsustoeffectivelyrunclean-upactivitiessuchasdeleting.tmpfilesandmovingfilesfromonefoldertoanother.
Let’sseehowtoaddtheshelltaskstoourGruntfile.AddthefollowinghighlightedpieceofcodetoyourGruntfile:
module.exports=function(grunt){//Projectconfiguration.grunt.initConfig({jshint:{all:['scripts.js']},concat:{dist:{src:['scripts.js','scripts1.js','scripts2.js'],dest:'merged.js'}},
uglify:{dist:{src:'merged.js',dest:'build/merged.min.js'}},
shell:{multiple:{command:['rm-rfmerged.js','mkdirdeploy','mvbuild/merged.min.jsdeploy/merged.min.js'].join('&&')}}});
grunt.loadNpmTasks('grunt-contrib-jshint');grunt.loadNpmTasks('grunt-contrib-concat');grunt.loadNpmTasks('grunt-contrib-uglify');grunt.loadNpmTasks('grunt-shell');//Defaulttask.grunt.registerTask('default',['jshint','concat','uglify','shell']);};
Asyoucanseefromthecodeweadded,wearefirstdeletingthemerged.jsfile,thencreatinganewfoldercalleddeployandmovingourmerged.min.jsfileintoit.WindowsuserswouldneedtousetheappropriateDOScommandsfordeletingandcopyingthe
-
files.
Notethat.join('&&')isusedwhenyouwantGrunttorunmultipleshellcommands.Thenextstepsaretoloadthenpmtasksandaddshelltothedefaulttasklist.ToseeGruntperformallthesetasks,runtheGruntcommandintheterminal.
Onceit’sdone,openupthefilesystemandverifywhetherGrunthasdonewhatyouhadaskedittodo.Justlikeweusedtheprecedingfourplugins,therearenumerousotherpluginsthatyoucanusewithGrunttoautomateyourtasks.
ApointtonoteiswhilethedefaultGruntcommandwillrunallthetasksmentionedinthegrunt.registerTaskstatement,ifyouwouldneedtorunaspecifictaskinsteadofallofthem,thenyoucansimplytypethefollowinginthecommandline:
gruntjshint
Alternatively,youcantypethefollowingcommand:
gruntconcat
Alternatively,youcantypethefollowingcommand:
gruntugligy
Attimesifyou’dliketorunjusttwoofthethreetasks,thenyoucanregisterthemseparatelyasanotherbundledtaskintheGruntfile.Openupthegruntfile.jsfile,andjustafterthelinewhereyouhaveregisteredthedefaulttask,addthefollowingcode:
grunt.registerTask('concat-min',['concat','uglify']);
Thiswillregisteranewtaskcalledconcat-minandwillrunonlytheconcatanduglifytasks.
Intheterminalrunthefollowingcommand:
gruntconcat-min
VerifywhetherGruntonlyconcatenatedandminifiedthefileanddidn’trunJSHintoryourshellcommands.
TipYoucanrungrunt--helptoseealistofallthetasksavailableinyourGruntfile.
-
Yeoman–theworkflowtoolYeomanpreferstobeknownasaworkflowratherthanjustatool.Itisactuallyacollectionofthreetoolsthathelpyoumanageyourworkflowefficiently.ThetoolsthatcomeasapartofYeomanareasfollows:
Yo:Thisisascaffoldingtoolandusingthenumerousgeneratorsavailable,onecanquicklycreatetheskeletonofyourproject.YohasageneratortobuildAngularJSappsandwewillbeusingthatlaterinthischapter.Grunt:Thisisusedtorunthetasksthatwillhelpyoupreview,test,andbuildtheapp.Bower:Thisisanidealtoolfordependencymanagement.Yeomanusesittoautomaticallysearchanddownloadthenecessaryscripts.
Let’sgoaboutinstallingYeomanandplayingaroundwithitabit.
-
InstallingYeomanToinstallYeoman,makesureyouarerunningitwithadministrativeprivileges.Enterthefollowingcommandintheterminal:
sudonpminstall–gyo
Next,let’sinstalltheAngularJSgeneratorusingthefollowingcommand:
sudonpminstall-ggenerator-angular
Now,let’screateourprojectdirectoryandcreatetheskeletonforourproject.WewillcallourappYoho;so,firstlet’screateafoldercalledyoho.Enterthefollowingcommandintheterminal:
mkdiryohocdyohoyoangular
It’snowgoingtostartaskingaseriesofquestions,answerYforallexceptthequestion,“WouldyouliketouseSass(withCompass)?”.AnswerNforthisone.
NoteThereasonwesaynohereisbecausefornowwewillusevanillaCSS.UsingSaasandCompassishoweverstronglyrecommendedwhilebuildinglargeapplications.
Onceyo-angularhasfinisheddoingwhateverithadtodo,gointoyouryohofolderandyou’llnoticeawholebunchoffilesandfolders,asshowninthefollowingscreenshot:
-
YeomanhascreatedtheskeletonofyourAngularJSappalongwitheverythingyouwillneedforthisproject.
Beforewegointothedetailsofthedifferentfiles,onethingtonoteisthatyournode_modulesfolderisempty.ThismeansYeomanhasonlycreatedthepackage.jsonfilewithalldevdependencieslistedout,buthasn’tdownloadedthemyet.
Wewillneedtorunthefollowingcommand:
npminstall
-
Thiswilldownloadandinstallallthedependencieslistedoutinthepackage.jsonfile.Onceit’sfinishedinstalling,verifythatthenode_modulesfoldernowhasfolderssuchasgrunt-contrib-cleanandgrunt-contrib-concatwithinit.
Ok,now,let’stryandmakesenseofallthefilesthatYeomanhascreated.Refertothefollowingtable:
Filename Description
app/404.html Thisisthe404errorpagethatwillshowup,whentheusertypesinawrongURLortheAngularappcouldn’tfindthepagementionedintheURL.
app/favicon.ico
Thisistheiconthatwillshowupinthebrowsertabofyourapp.Makesureyoureplacethisdefaultonewithaniconthatrepresentsyourapp.Feelfreetouseanyofthosenumerousonlinefavicongeneratorstocreateyourfavicon.Rememberthatthisfaviconhelpsuserstoquicklyidentifyyourappwithinthemultipletabsofanopenbrowser.
app/index.html
Thiswillbethehomepageforyourapp.Youcanopenitinatexteditortoseewhatitcontains.Asyouwouldhavenoticed,otherthanthatonelineofcodewiththeng-viewsdirective,therestofthefileismostlybrowserchecksandinclusionofthevariousJavaScriptfiles.NotethatthereisnoactualAngularJScodeotherthanng-viewsandthat’showitneedstobekepttoo.
robots.txtThisisthefilewhereyousetrulesforthesearchenginerobotsorcrawlers,tellingthemwhatpagestheycanindexandwhichsectionsoftheappshouldnotbeindexed.
scripts/app.js
Thisistheroute’sfilewhereyou’lldefinethetemplateviewandthecontrollerthatshouldloadforagivenURL.ControllersandviewsarelooselycoupledinAngularJS;thismeansyoucanhaveasinglecontrollertalktodifferentviews,orswapthetemplatesforacontrollerbysimplyeditingtheroutesinthisapp.jsfile.
scripts/controllers/main.jsscripts/controllers/about.js
Thisiswhereyou’llbewritingthecontrollersforthisapp.Asapartofthescaffolding,YeomanwouldhavealreadycreatedadefaultMainCtrlandAboutCtrlcontrollerswithamodelcreatedineach.Feelfreetomodifyitand/orwritetherestofyourcontrollersinthesamefile.
styles/main.cssAllyourCSScodewouldgointothisfile.Thestylesfolderwouldalsocontainthebootstrap.cssfile.ThiscontainsalltheBootstrapclasses.Makesureyoudon’tmodifyanyofthecodehereoraddanyadditionalCSSinthebootstrapfile.
views/about.htmlviews/main.html
Theviewsfolderwouldcontainallthetemplateviewsorpartialsastheyarealsocalledtoloadwithintheng-viewstagoftheindex.htmlfile.Theroutesdefinedinthescripts/apps.jsfilewouldcontrolwhatviewwillbedisplayedforthegivenURL.
Bower_components:ThiscontainsfoldersforthevariousvendorlibrariessuchasAngularJS,AngularAnimate,jQuery,andBootstrapanditisusedfordependencymanagementoftheselibraries.
bower.json Thebower.jsonfilekeepsatrackofthedependenciesanddevdependenciesofthevariousmodulesandpluginsforthisapp.
YouknowwhattheGruntfileisforright?Openitinatexteditorandbeoverwhelmedbythe300pluslinesofcodeinthefile.You’llseeabunchof
-
Gruntfile.js predefinedtasksandyou’llalsonoticethatbesidesthedefaultbundledtask,youalsohavetaskscalledtestandbuild.Thesecanbeusedtopreviewyourappandfinallybuilditreadyfordeployment.
test/karma.conf.js
Thekarma.conf.jsfileistheconfigurationfileforrunningKarmaunittests.Openingthisfilewillshowthetestingframeworkweareusing,listfilesthatwewanttoincludewithinthescopeoftheseunittests,whatporttouse,thebrowsertouse,andsoon.
node_modules
Asself-explanatoryasitcanbe,thisfoldercontainsthevariousNode.jsmodulesthatweredefinedinthepackage.jsonfile.Notethatthesemodulesdonotgetinstalledwhenyouruntheyo-angularcommand.Thesewoulddownloadandinstallonlyafteryourunthenpm-installcommandafterthecreationofthepackage.jsonfile.
package.jsonThisfilelistsoutalltheNode.jsmodulesthatneedtobeinstalled.Youmayeditthisfilewithcautiontoaddmoreorremovedependenciesthatyouthinkarenotneededforyourapp.
test/spec/controllers/main.js
Thisisthefilewhereyou’dwritetheunittestsforyourcontrollers.Themain.jsfilewouldalreadyhaveasimpleunittestinit.
ThedefaultconfigurationofYeomanusesJasmine;youcanchangetheconfigurationstouseMochaorQunitframeworks.
Let’sinstallourNode.jsmodulesbyrunningthefollowingcommandintheterminal:
npminstall
-
RunningyourappEarlierinthischapter,wesawhowtosetupaserverusingNode.jsandExpressJS.Yeomancomeswithitsownserverandrunningitisassimpleasrunningthefollowingcommandinyourterminal:
gruntserve
TipThegruntservercommandisdeprecatedalthoughitmightstillworkforsome.
Thiswillopenupanewbrowserwindowandwillshowyouthedefaultwelcomescreen,asshowninthefollowingscreenshot:
Ifyourecollectlookingatthemain.jsfile(underscripts/controllers)andthe
-
main.htmlfile(underviews),you’llnoticethepagethatisbeingrendered.Let’splayaroundabit.
Openthescripts/controllers/main.jsfileandyou’llfindacontrollercalledMainCtrlandamodelcalledawesomeThings.Let’saddsomemoreitemstothisarrayasfollows:
'usestrict';
angular.module('yohoApp').controller('MainCtrl',function($scope){$scope.awesomeThings=['HTML5Boilerplate','AngularJS','Karma','E2E','Protractor'
];});
Let’sdisplayourawesomeThingsarrayintheview.Pleaseaddthefollowingcodetothemain.htmlfileasfollows:
{{things}}
Savethefileandswitchtothebrowser.VOILA!Thepageupdatedonitsown,youdidn’thavetoreloadthepageinthebrowser.
Thebrowserupdatesthemomentyousaveyourfile,nomorehittingtherefreshbutton.Isn’tthatabigreliefandaproductivityboost!
ThisworksthankstoaniftymodulecalledLiveReload.You’llfindthisbeinginstalledasapartofdevDependenciesinthepackage.jsonfile.You’llalsonoticeGrunttasksforitcreatedinyourgruntfile.jsfile.
Sonowyoucanhavetheserverrunningandplaceyourbrowserwindowandyourtexteditorarrangedside-by-side,andwatchyourappupdateasyouwriteyourcodeandsavethefile.
-
UnittestingwithKarmaWritingautomatedunittestsforyourAngularJSappisoneofthebestpractices,theAngularJSteamhasbeenstronglyadvocatingthisrightfromthestart.Everysamplecodeonthewww.Angularjs.orgsitehasautomatedtestcasesalongwithit.
Keepinginlinewiththesamephilosophy,YeomantoobakesinsomesampleunittestsusingKarma.WhileYeomanwouldautomaticallyinstallKarmaanditsdependencies,letus,nevertheless,makesurethefollowingmodulesarepresentinthenode_modulesfolder:
karmakarma-chrome-launcherkarma-jasmine
Incaseyoudon’tfindtheminyournode_modulesfolder,installthemusingthenpminstallcommand.Next,makesureyourkarma.conf.jsfilelookslikethefollowing:
module.exports=function(config){config.set({basePath:'',frameworks:['jasmine'],files:['bower_components/angular/angular.js','bower_components/angular-mocks/angular-mocks.js','bower_components/angular-animate/angular-animate.js','bower_components/angular-resource/angular-resource.js','bower_components/angular-cookies/angular-cookies.js','bower_components/angular-route/angular-route.js','bower_components/angular-sanitize/angular-sanitize.js','bower_components/angular-touch/angular-touch.js','app/app.js','app/scripts/*.js','app/scripts/**/*.js','test/spec/**/*.js'],exclude:[],preprocessors:{},reporters:['progress'],port:9876,colors:true,logLevel:config.LOG_INFO,autoWatch:true,browsers:['Chrome'],singleRun:false});};
Torunyourunittests,simplyrunthefollowingcommandintheterminal:
grunttest
http://www.Angularjs.org
-
ThiswillfireupanewChromebrowserwindowandintheterminalstartrunningthroughyourtests.Refertothefollowingscreenshot:
Oh!WegotanerrorinMainCtrl.ItwouldsaysomethinglikeExpected5tobe3andpointyoutoanerrorinthefilelocatedattest/spec/controllers/main.js.
Let’sopenupthisfileandseewhat’sgoingoninthere.Thetestcasethat’sfailingisasfollows:
it('shouldattachalistofawesomeThingstothescope',function(){expect(scope.awesomeThings.length).toBe(3);});
Ifyourecollect,earlierwehadmodifiedourawesomeThingscontrollerandaddedsomeadditionalelementstothearray,theprecedingtestcaseisexpectingthelengthofthatarraytobe3.Let’snowmodifythatstatementtothefollowingcode:
expect(scope.awesomeThings.length).toBeGreaterThan(3);
Let’ssavethisfileandrerunthefollowingcommand:
grunttest
ThetestcasesshouldrunfinewithamessagesayingExecuted2of2SUCCESS…….Done,withouterrors.WewillbewritingmoreunittestswithKarmaintheforthcomingchapters.
-
UsingProtractorforEnd-to-EndtestsAswesawearlierwithKarma,wecanwriteunitteststhatwillmakesurethatourcodeinthecontrollersisworkingwell;however,itwouldfallshortifyouwantedtorunautomatedUserAcceptanceTests(UAT)orrunteststhatsimulateuser-driveninteractionswiththebrowser.Forrunningsuchtests,we’llneedtouseanothernewtoolcalledProtractor.
ProtractorreplacestheearlierAngularJSscenariosasthedefaultEnd-to-EndtestingframeworkfortestingAngularJSapps.
ProtractorrunsonWebDriver.js,whichinturnmakesuseoftheSeleniumServer.Seleniumisoneofthemostpopularbrowser-automationtools.Inthissection,wewillseehowtosetupastandaloneinstanceofSeleniumServer,installProtractor,andrunadefaultsetofEnd-to-Endtestswithit.
Let’sfirstinstallProtractorbyrunningthefollowingcommandintheterminal:
sudonpminstall–gprotractor
ThiswillinstallProtractorglobally.
-
InstallingSeleniumServerProtractorcomeswithahandyscriptcalledwebdriver-managerthatcanbeusedtodownloadandruntheSeleniumServer.
Intheterminal,typeinthefollowingcommandtodownloadSeleniumServer:
webdriver-managerupdate
Tostarttheserver,typeinthefollowingcommand:
webdriver-managerstart
ThisshouldstartyourSeleniumServer.Nowopenyourbrowserandtypeinthehttp://localhost:4444/wd/hub/static/resource/hub.htmladdressintheaddressbar.ThiswillshowyouthecurrentstatusoftheSeleniumServer.
Theprotractorfolderwithinthenode_modulescomeswithacoupleofdefaultteststhatcanhelpyoujumpstart,writingyourEnd-to-Endtests.Thesetestsarelocatedintheusr/local/lib/node_modules/protractor/examplefolder.
Dependingonwhatyouarecomfortablewith,youcanchoosebetweenJasmineandMochaforwritingyourtestcases.Fromtheexamplefolderunderprotractor,copytheconf.jsandtheexample_spec.jsfilesandpastethemintoanewtest/protractor-testsfolder.
-
Understandingtheexample_spec.jsfileTheexample_spec.jsfileisthespecsfilewherethetestcasesarewritten.Let’sopenthisfileinaneditorandtryandmakesenseofwhatitisgoingtodo.
Wefirstdescribeourtestsuiteasfollows:
describe('angularjshomepage',function(){})
Next,let’slookatthetestcase.Thefirsttestcaselookssomethinglikethefollowing:
it('shouldgreetthenameduser',function(){browser.get('http://www.angularjs.org');
element(by.model('yourName')).sendKeys('Julie');
vargreeting=element(by.binding('yourName'));
expect(greeting.getText()).toEqual('HelloJulie!');});
Thefirstlinedescribesthetestcase.Inthenextline,wenavigatetothedefinedURL;inthiscaseweloadthewww.angularjs.orghomepage.
Oncethehomepageisloaded,inthenextstepthecodeistryingtolocateaninputfieldboundtoamodelcalledyourNameandtypeinthetextJulie.ItthenlooksfortheexpressioncalledHello{{yourName}}andverifiesthatthetextreadsHelloJulie.
Let’slookatthesecondtestsuite,whichhastwotestcasesasfollows:
describe('todoList',function(){vartodoList;
WedefinethesuitenameandinitializetodoList.NowsinceboththetestcasesneedtogotothesameURLandwillbebasedontodoList,weusebeforeEachtosettheURLandloadthecontentintoourtodoListarrayasfollows:
beforeEach(function(){browser.get('http://www.angularjs.org');
todoList=element.all(by.repeater('todointodos'));});
ThefirsttestcasecheckstoseeifwehavetwoitemsintodoListandthattheseconditemiscalledbuildanangularapp.Refertothefollowingcode:
it('shouldlisttodos',function(){expect(todoList.count()).toEqual(2);expect(todoList.get(1).getText()).toEqual('buildanangularapp');});
ThesecondtestcasewillsimulateaddinganitemtotodolistbylocatingthetodoTextmodel,andaddinginandverifyingthetextbeingaddedasfollows:
it('shouldaddatodo',function(){varaddTodo=element(by.model('todoText'));
http://www.angularjs.org
-
varaddButton=element(by.css('[value="add"]'));
addTodo.sendKeys('writeaprotractortest');addButton.click();
expect(todoList.count()).toEqual(3);expect(todoList.get(2).getText()).toEqual('writeaprotractortest');});
})
-
Understandingtheconf.jsfileTheconf.jsfileistheconfigurationfile.Openitinaneditorandyou’llseetheconfigurationsettingssuchasthedefaultaddressfortheSeleniumServer,thebaseURL,thebrowsertobeusedfortesting,andthelocationofyourtestcases.Now,sincewehavetheexample_spec.jsfileinthesamepathasourconf.jsfile,let’scorrectthepathofthespecstoreadasfollows:
specs:[example_spec.js'],
Torunourtestsuite,opentheterminalandnavigatetotheyohofolderandtypeinthefollowingcommand:
protractortest/protractor-tests/conf.js
Thiswilllaunchabrowserinstanceandseethestepsbeingperformedbythescript.Thebrowserwillautomaticallycloseoncethescriptisexecutedandtheterminalwindowshoulddisplaythefollowingmessage:
Finishedinxxx.xxxxseconds
2tests,2assertions,0failures
NoteSometimesyoumightstartgettingerrorslikeError:ECONNREFUSEDconnectECONNREFUSED.InsuchacaserestartyourSeleniumStandaloneServerandwebserver.
-
WritingyourownProtractortestcasesNowthatweknowhowtestcasesarewritteninProtractorandhowtorunthem,let’squicklywriteacoupleofourowntestcasesagainstthedefaultscaffoldapplicationthatYeomancreatedforus.
Let’screateanewfilecalledmytests.jsinthetestfolderunderyoho/protractor-tests.Nowwecanstartwritingoutourtestcasesasfollows:
describe('ourhomepage',function(){})
Thefirsttestcasewewillwriteistheonewherewe’llchecktoseeifthepageheadingwithintheh1tagssays‘AlloAllo!'.Thetestcaseforthatwouldlooksomethinglikethefollowing:
it('shouldsayAllo',function(){browser.get('http://localhost:9000/#/');varheading=element(by.tagName('h1'))expect(heading.getText()).toEqual("'Allo,'Allo!")});
Thebrowser.getfunctiondefinestheURLofthepageyou’dwantProtractortonavigateto.Weusetheby.tagNameselectortolocatetheh1tagandgetthetextwithinitandverifythatitmatches"'Allo,'Allo!".
Let’swriteoursecondtestcase.Here,wewanttoensurethatthewidthofourpageiswithintherecommendedlimitsandisn’tgoingbeyondthescreensizeofmostcommonusers.Refertothefollowingcode:
it('shouldnotbegreaterthan940px',function(){browser.get('http://localhost:9000/#/')element(by.className('container')).getSize().then(function(size){expect(size.width).toBeLessThan(950)})})
Here,weareusingtheby.classNameselectortoidentifythecontainerdivandusingthegetSizepropertywechecktomakesurethatthewidthisnotgreaterthan950px.
Noticethatthe.then()functionisapartofapromise,whichensuresthatthecodewaitsfortheresulttobereturned.We’llseepromisesindetailinChapter4,UsingRESTWebServicesinYourAngularJSApp.Fornow,savethefile.
Nowthatwehaveourtestcase’sspecsfileready,weneedtocallitwithintheprotractorconfigurationfile.Let’sopentheconf.jsfileandchangethefilenameinthespecsarraytopointtoourmytest.jsfileasfollows:
specs:['mytests.js'],
Wearenowsettotestourscripts.First,let’sstartourserverbyrunningthefollowingcommand:
cdyohogruntserve
-
Thisshouldstartourserver.Now,let’srunourprotractortestscriptbyrunningthefollowingcommandfromwithintheyohofolder:
protractortest/protractor-tests/conf.js
MakesureyouhaveyourSeleniumStandaloneServerrunning;ifnot,startitusingthefollowingcommand:
webdriver-managerstart
Ifallgoeswell,youcouldseetheChromebrowserbeinglaunched,andseethescriptnavigatetothelocalhost:9000/#/URLandthebrowserwindowclosingdownaftersometime.
Switchtoyourterminaltoseethestatussayingthefollowingingreenthatmeansourtestcasesworked:
Finishedinx.xxxseconds
2tests,2assertions,0failures
NoteIncaseyou’dliketorunyourtestcaseswithouthavingtolaunchthebrowserwindoweachtimeorifyou’dwanttorunitheadlessonaserver,thenhavealookatPhantomJS(http://phantomjs.org/),whichisanexcellentheadlessbrowserthatrunsontheWebKitengine.
http://phantomjs.org/
-
SummaryThiscompletesourchapteronsettingupyourrig.Weworkedthroughquiteafewtools,namelyNode.js,Grunt,Yeoman,Karma,andProtractor.WhileIstronglyrecommendmakinguseofallofthemwhenyoubuildyourAngularJSprojects,youmayfeelfreetochoosetheonesthatsuityourprojectthebest.
AnotherthingtonoteisthatmostofthesetoolssuchasNode.js,ExpressJS,andGruntcanbeusedforanynon-AngularJSprojects.Sogettingfamiliarwiththesetoolsissurelybeneficialforallfrontenddevelopers.
Inthenextchapter,wearegoingtoseehowtoquicklybuildaclickableprototypeusingAngular-UI.
-
Chapter3.RapidPrototypingwithAngularJSInthepreviouschapter,wesawhowtosetupthevarioustoolsthatwillaidinbuildingourAngularJSapp.Inthischapter,wewillseehowAngularJSlendsitselfasanexcellenttooltocreateprototypes.
RapidPrototypingisanexcellentwayofvalidatingthegoalsofthewebapplicationyouareplanningtobuild.Itgivesusefulandimportantfeedbackfromusersandstakeholdersonvariousaspectsoftheapplication,suchasuserclickflows,usabilityissues,andusefulnessoftherequirementspecificationsthatwereinitiallyoutlined.
Inthepast,prototypeswerebuiltusingeitherwireframingtools,ordeveloperswouldcreateaseriesofHTMLpageslinkedwitheachotherthatwouldmimicthefunctioningofthewebapplication.Whiletheformernevergavetherightfeelofhowtheappwouldlookandbehave,thelatterwouldtakeamuchlongertimetobuild,especiallyifitwasalargeapplication.
Now,thankstoAngularJS,buildingsuchprototypeshasbecomealoteasier,andonecanbuildnearlyfunctionalprototypewithinashorttimeframeandwithsignificantlylesscode.
Inthischapter,wewilldothefollowing:
RunthroughthevariouscomponentsoftheapplicationthatwearegoingtoprototypeUnderstandGridLayoutsandseehowBootstrapworksAddUIcomponentssuchascarousels,accordions,andmodalwindowsusingAngularUILearnthemodularwaytobuildpagesusingpartialsCreatedummydatamodelstosimulatedynamicdataUseroutestolinkthecontrollerstotheviews
-
UnderstandingtheapplicationthatwewillPrototypeWewillcreateaclickableprototypeofapseudowebappnamedHealthyLiving.Itwillconsistoffourpages.Theyareasfollows:
Homepage:Thiswillconsistofacarousel,herounit,andthreemaincontentblocks.Articles:Thisdisplayalistofarticlesinanaccordionview.Gallery:Thisisanimagegallerypagewithpictures,atitle,ashortdescription,andastarrating.Subscribers:ThispagewilldisplaythelistofsubscribersinaninteractivedatagridwithfeaturestogroupbyacolumnandExcel-styleinlineediting.Thesubscriptionpagewillalsohaveabuttonthatwillallowustoaddanewuserviaamodalwindow.
-
IntroducingGridLayoutsandBootstrapBuildingHTMLpageshadalwaysbeenawebdesigner’sjob,andprogrammerswouldrunmilesawayifaskedtobuildanHTMLpage.
AnotherproblemwithdesigningHTMLpagesisthateverydesignerhastheirownsecretrecipetocreateanHTMLpage,usingtheirownstructuretolayouttheDOMelementsandtheirfavoriteCSSclassnames.ThiscausesquiteananguishwhendeveloperstakeoverHTMLtoputinthedynamiccode,orwhentwodesignersareworkingonthesameproject.
TheGridLayoutsevolvedasameanstohelpgeteverybodyonthesamepageintermsofnamingconventionsandtheDOMstructure,andmoreimportantly,toreducethetimetakentobuildHTMLpageswhileensuringafairamountofbrowsercompatibilityatthesametime.
Whilegridsystemssuchasthe960GridSystemandBlueprintwereamongtheearlygridsystemsavailable,nowadays,Bootstrap,Foundation,andSemanticUIhavebecomeverypopulartoolstobuildfrontendpages.
Atthetimeofwritingthisbook,theversionofBootstrapthatiscompatiblewithAngularUIis3.1.x,andwewillbeusingthistobuildourprototype.
-
UnderstandingthegridsystemOflate,gridsystemshavebeenextensivelyusedinweb-developmentworkflows.GridsystemsaimtostreamlinetheHTMLmarkupprocessbyprovidingastandardsetofdimensionsanddisplaystylesforthecommonlyusedUIelements.Thefollowingscreenshotshowsagridsystem:
Bootstraphasadefault12-columngridsystemthatisavailableasaresponsive,fluid,andfixedlayout.ItcomeswithacompletesetofpredefinedclassesthatmeetsnearlyallyourUIstylingneeds.
Someofthemostcommonlyusedclassesarementionedinthefollowingtable:
Class Description
.col-md-* Thisisforcolumnwidthsthatareappliedtoacontentblockformediumscreendevicessuchasdesktopswithresolutionsgreaterthanorequalto992pxwide.
.col-xs-* Thisisforsmalldeviceswithawidthof768pxorless.
.col-sm-* Thisisfortabletdeviceswithasizeof768pxormore.
.col-lg-* Thisisforlargedeviceswithsizesgreaterthanorequalto1200px.
.col-md-offset-* Theoffsetclassisusedtoleavecolumnspacingfromtheleft.
.row
.row-fluidThe.rowclassisusedtoseparatethedatarowwise.The.row-fluidclassisusedincaseofafluidlayout.
.container
.container-fluid
The.containerclasswillsettheelementwidthto940pxandwillcenterithorizontallywithrespecttothepage.The.container-fluidclassisusedincaseofafluidlayout.
.lead Thisisusedtomakeaparagraphstandout.Itismostcommonlyusedwithinaherounitortodisplaythepagesummaryunderthepageheading.
.text-left
.text-center
.text-rightTheseareusedtoalignthetexttotheleft,centerandrightrespectively.
-
Theandtagsareusedtoquotesomebody,andtheandtagsareusedtowrapthenameofthesource.
.pull-left
.pull-rightTheseareusedtofloatanelementandpushiteithertotheleftorrightofitsboundingcontainer.
.btnprimary
.btn-success
.btn-info
.btn-warning
.btn-danger
.btn-inverse
Theseareusedtostylethebuttonsoranchorelements;theseclassesapplydifferentcolorstothebuttonrangingfrombluetoblack.
Atthemostminimum,BootstrapcomeswithaCSSandJavaScriptfilealongwithanimage(/img)foldercontainingtheglyphicons.TheCSSfilecontainsallthestylesforthegridsystemandthepredefinedclassesforthevariousUIcomponents.JavaScriptcontainsthelibrariestobuildUIwidgetssuchasaccordions,tabs,modalwindows,progressbars,datepickers,andsoon.
-
IntroducingAngularUIAngularUIisabunchofminiprojectsthathelpsyoubemoreproductivewithyourAngularappdevelopment.Atthetimeofwritingthisbook,AngularUIconsistedofprojectsdiscussedinthefollowingsections.
-
UI-UtilsUI-Utilsisautilitypackagethatallowsyoutoaddawidevarietyofutilitiesintoyourapplication.Theutilitiesareexplainedasfollows:
IEShiv:ThisisusedtoallowsupportforcustomtagsinIE8andbelow.jQueryPassthrough:TheuiJqdirectiveallowsustousejQuerypluginsdirectlyinsteadofhavingtocreatenewdirectivestousethem.EventBinder:ThisallowsyoutobindcallbackstoeventsthatarenotnativelysupportedinAngularJS.Keypress:Thisallowsyoutobindeventstoakeypress.Mask:Thisallowsyoutomaskdatabasedoncertainconditionsset.Validate:ThisallowsyoutocreatecustomvalidatorsandexpressionsReset:Thisallowsyoutodisplayaniconorlink;ifyouclickonit,themodelwillbecomeempty.Scrollfix:Thisaddsaui-scrollfixclasstotheelement.Show/Hide/Toggle:Thisallowsyoutouseasingledirectiveofui-toggleinsteadofusingng-showandng-hide.RouteMatching:Thisisaniftylittledirectivethatcanbeusedtomatchtherouteofthecurrentpage.Highlight:Thisisusedtohighlightastringofcharacterswithinascopemodel.Inflector:ThiswillhelpyouconvertastringintoalternativeformatssuchasreplacespaceswithunderscoresorconvertthestringintoacamelCasesyntax.Unique:Thiscanbeusedtoremoveallduplicateitemsfromwithinanarray.Format:Thisfiltercanbeusedtodoanykindofstringreplacement.
-
UI-ModulesTheUI-ModulesprojectallowsyoutoeasilyaddCalendarControls,GoogleMaps,andabunchofeditorssuchasTinyMCEandCodeMirrorAce.
-
UI-BootstrapUI-BootstrapisthenativeimplementationofTwitterBootstrapwithinAngular.Aswe’llseefurtherinthischapter,addingUIcontrols,suchascarousels,accordions,andtabs,isabreezeusingUI-Bootstrap.ItisworthnotingthatUI-BootstrapusestheoriginalCSSandglyphiconsofBootstrapastheyare.It’sonlytheJavaScriptfilethathasbeenrewrittentousenativeAngulardirectives.
-
NG-GridNG-GridallowsyoutoadddatagridsinyourAngularapp.NG-GridcomeswithquiteafewcustomizationoptionsthatallowyoutoplacegridswithsortablecolumnstofeaturessuchasExcel-styleediting,inplace.
-
UI-RouterUI-RouterisanewwayofroutingthatallowsyoutocreateNestedRouting.
-
IDEPluginsIDEPluginsareabunchofpluginsorextensionsthatprovideAngularJSsupportinvarioustexteditors.
Aswemoveaheadinthechapter,wewillmakeextensiveuseoftheUI-BootstrapandNG-Gridprojects.
-
PrototypingtheHealthyLivingwebsiteForthisexercise,wearegoingtocreateafour-pageclickableprototypeofapseudowebsitecalledHealthyLiving.Thehomepagewillconsistofafullyfunctionalcarousel,herounit,andthreecontentsectionswithcalltoactions.Thefollowingscreenshotisthatofthehomepage:
Let’sgetstartedwiththecreationofourapplication.We’llstartbyperformingthefollowingsteps:
1. Createafoldernamedhl,shortfor“HealthyLiving”.2. AssumingthatyouhavealreadyinstalledYeoman,openuptheterminal.Let’screate
thescaffoldingforourappusingthefollowinglinesofcode:
-
mkdirhlcdhlyoangular
NoteGenerator-AngularmustbeinstalledbeforeyoucanrunyourAngularapp.Incaseyouhaven’tinstalleditduringChapter2,SettingUpYourRig,pleaseinstallitusingthefollowingcommand:
sudonpminstall–ggenerator-angular
3. Intheprompt,pressYforthequestion,WouldyouliketoincludeTwitterBootstrap?.
4. Forthequestion,WouldyouliketouseSass(withCompass)?,pressN.5. Forthethirdquestion,pressEntertoacceptthedefaultsettings.
NoteUsingaCSSpreprocessorsuchasSASSorLESSisalwaysagoodpracticeasitallowsyoutousevariablesandmixinsinCSS,ensuringthatyourCSSremainsmodularandfollowsDRY(Don’tRepeatYourself)principals.However,coveringthemisbeyondthescopeofthisbook.
Youshouldbeseeingnpmpullingabunchoffilesandcreatingthescaffoldofyourapp.Waitpatientlyuntilitisalldoneandyouarereturnedbacktothecommandprompt.
Youshouldnowbeabletoseethestructureofyourapplicationwiththedefaulthomepage.
AswearegoingtobeusingUI-Bootstrap,let’sinstallitusingBower.
6. Firethefollowingcommandintheterminal:
bowerinstallangular-bootstrap
Thiswillcreatetheangular-bootstrapfolderwithintheapp/bower_componentsfolder.
TobeabletouseAngularBootstrapinourapplication,weneedtoincludetheJSfile.
7. Let’sopenuptheapp/index.htmlfileandaddthefollowinghighlightedline.
Ifyoulookintothebower_components/angular-bootstrapfolder,you’llnoticetherearethefollowingtwotypesoffilesalongwiththeirminifiedversions:
ui-bootstrap.js:Thiscontainsallthedirectives,butitdoesn’tcontainanytemplates.Itmakessensetousethisfileifyoudonotwanttousethedefaulttemplatesbutwanttocustomizeyourtemplatesfromscratch.
-
ui-bootstrap-tpls.js:Thiscontainsallthedirectivesalongwiththedefaulttwitterbootstraptemplatecode.Ifyouarenotlookingtomakeanycustomization,thenitsbesttoincludethisfileinyourproject.
-
Addingtheui.bootstrapdependencyThenextstepistoaddtheAngularBootstrapdependencytotheAngularapp.
Wedothisbymodifyingthefollowinglineintheapp/scripts/app.jsfile:
angular.module('hlApp',['ui.bootstrap'])
Now,angular-bootstrapwillbeavailableforuseacrossourapplication.
-
CreatingthenavigationbarTocreatethenavigationbar,let’sopenuptheapp/index.htmlfileandaddthepartofthecode,whichisshownasfollows:
HealthyLiving
ArticlesGallerySubscribers
Asyoucanseefromtheprecedingcode,wedefinedtheheadertagandappliedtheCSSclasses,navbarandnavbar-fixed-top,toit.ThesearepredefinedbootstrapCSSclassesthatareusedtostylethenavigationbar.
ThenavbarclassisadefaultcontainerthatsetstheoverflowtovisibleforallelementswithinthenavbarDOM.
Thenavbar-fixed-topclasswillmakethenavigationbarsticktothetopofthepage,anditwillstayfixedevenasthepagescrolls.Youcanalsousenavbar-fixed-bottomtomakeyournavigationbarsticktothebottomofthepage.
Now,we’lladdthetagwithaclassnamedcontainer.Thecontainerclasswillsetthewidthofthiselementto940pxandalsocentertheelementhorizontallyonthepage.
WewilladdourHealthyLivingwebsitewithinananchortagandgiveitaclassnamednavbar-brand,asthisiswhatourbrandnameissupposedtobe.
NavigationlinksfortheArticles,Gallery,an
top related