Mastering Web Application

Transcription

Mastering Web ApplicationDevelopment with AngularJSBuild single-page web applications using the power ofAngularJSPawel KozlowskiPeter Bacon DarwinBIRMINGHAM - MUMBAI

Mastering Web ApplicationDevelopment with AngularJSCopyright 2013 Packt PublishingAll rights reserved. No part of this book may be reproduced, stored in a retrievalsystem, or transmitted in any form or by any means, without the prior writtenpermission of the publisher, except in the case of brief quotations embedded incritical articles or reviews.Every effort has been made in the preparation of this book to ensure the accuracyof the information presented. However, the information contained in this book issold without warranty, either express or implied. Neither the authors, nor PacktPublishing, and its dealers and distributors will be held liable for any damagescaused or alleged to be caused directly or indirectly by this book.Packt Publishing has endeavored to provide trademark information about all of thecompanies and products mentioned in this book by the appropriate use of capitals.However, Packt Publishing cannot guarantee the accuracy of this information.First published: August 2013Production Reference: 1170813Published by Packt Publishing Ltd.Livery Place35 Livery StreetBirmingham B3 2PB, UK.ISBN 978-1-78216-182-0www.packtpub.comCover Image by Abhishek Pandey (abhishek.pandey1210@gmail.com)

CreditsAuthorsProject CoordinatorsPawel KozlowskiArshad SopariwalaPeter Bacon DarwinPriyanka GoelReviewersProofreadersStephane BissonJudith BillMiško HeveryBernadette WatkinsLee HowardIndexerAcquisition EditorsMonica Ajmera MehtaRukhsana KhambattaPramila BalanLead Technical EditorGraphicsRonak DhruvAbhinash SahuDayan HyamesProduction CoordinatorTechnical EditorsAditi GajjarShashank DesaiKrishnaveni HaridasSaumya KunderCover WorkAditi Gajjar

About the AuthorsPawel Kozlowski has over 15 years of professional experience in webdevelopment and was fortunate enough to work with variety of web technologies,languages, and platforms. He is not afraid of hacking both at client side and serverside and always searches for the most productive tools and processes.Pawel strongly believes in free, open source software. He has been very committedin the AngularJS project and also is very active in the AngularJS community. He alsocontributes to Angular UI – the companion suite to the AngularJS framework, wherehe focuses on the Twitter's Bootstrap directives for AngularJS.When not coding, Pawel spreads a good word about AngularJS at various conferencesand meetups.

AcknowledgmentsReflecting on the last few months I can't believe how fortunate I was to work on thisbook with so many great people. This text wouldn't have been possible without allthe help and hard work of you all. Thank you.Firstly I would like to say a "Thank you" to all the members of the AngularJS teamat Google. You are the dream team working on an amazing framework. Keep upthe great work! My special thanks go to Brad Green, Miško Hevery, Igor Minar, andVojta Jína. Brad, thank you for putting Peter and me in contact with the publisherand encouraging us to write this book. Miško, thank you for reviewing our bookand bearing with us when we had naive questions about AngularJS. Igor, for yourconstant support and an endless stream of good hints, which made this book muchbetter. It was a lot of fun to work with all of you guys.I would like to extend my gratitude to the entire AngularJS community, especially topeople with whom I've interacted on the mailing list and other forums. I can't nameyou all, but your insightful questions were great inspiration for this book. A vibrant,supportive community behind AngularJS is one more reason why this framework isso great.Thanks are due to all the people at Packt Publishing: Rukhsana Khambatta, DayanHyames, and Arshad Sopariwala. You've made the entire writing and publishingprocess very smooth and straightforward. Thank you.

I would like to thank my co-workers at Amadeus, where I've learned what ittakes to be a client-side programmer. Firstly, my managers Bertrand Laporte andBruno Chabrier. Bertrand, thank you for introducing me to the world of client-sidedevelopment and encouraging me to write this book. Bruno, thank you for lettingme work part time and focus on this project. Thank you both for your generosity.Thanks to Julian Descottes and Corinne Krych, who reviewed an earlier draft of thebook and provided valuable feedback.Very, very special thanks to Peter who agreed to co-author this book with me. Peter,I've throughly enjoyed every minute of working with you on this project. I couldhardly dream of a better co-author.Lastly, but most importantly, I would like to thank my wonderful soon-to-be wifeAnia. Without your unconditional support and patience I wouldn't have eventhought of starting work on this book.

About the AuthorsPeter Bacon Darwin has been programming for over two decades. He worked with.NET from before it was released; he contributed to the development of IronRuby andwas an IT consultant for Avanade and IMGROUP before quitting to share his timebetween freelance development and looking after his kids.Peter is a notable figure in the AngularJS community. He has recently joined theAngularJS team at Google as an external contractor and is a founder member of theAngularUI project. He has spoken about AngularJS at Devoxx UK and numerousLondon meetups. He also runs training courses in AngularJS. His consultancypractice is now primarily focused on helping businesses make best use of AngularJS.I would like to thank the team at Google for giving us AngularJS, inparticular the ones who got it all going: Miško Hevery, Igor Minar,Brad Green, and Vojta Jína. They are a constant inspiration. My coauthor, Pawel, is the driving force behind this book. He conceivedthe structure, wrote most of the content, and is a great guy to workwith. We have all benefited from the awesome active communitythat has built up around AngularJS in such a short time, especiallythe folks in the AngularUI project. Finally, I couldn't have completedthe book without the love and support of my wife, Kelyn, and kids,Lily and Zachary.

About the ReviewersStephane Bisson has been a developer at ThoughtWorks, a global IT consultancy.He is currently based in Toronto, Canada. He has also worked on several rich webapplications for medical, financial, and manufacturing industries.Miško Hevery has been working as an Agile Coach at Google where he isresponsible for coaching Googlers to maintain the high level of automated testingculture. This allows Google to do frequent releases of its web applications withconsistent high quality. Previously he worked at Adobe, Sun Microsystems, Intel,and Xerox, where he became an expert in building web applications using webrelated technologies such as Java, JavaScript, Flex, and ActionScript. He is veryinvolved in open source community and is an author of several open source projects,most notable of which is AngularJS (http://angularjs.org).Lee Howard has a Computer Science degree from Appalachian State Universityand is currently the lead programmer analyst for the Northwest Area HealthEducation Center at Wake Forest Baptist Health Medical Center in Winston-Salem,NC. He has developed a variety of web applications to facilitate the creation,registration, delivery, and completion of live and the online continuing medicaleducation courses for the Northwest AHEC. He has also developed NorthwestAHEC's CreditTrakr mobile app for IOS devices, which allows physicians and othermedical professionals to track their CME credits with their IOS devices.

www.PacktPub.comSupport files, eBooks, discount offers and moreYou might want to visit www.PacktPub.com for support files and downloads relatedto your book.Did you know that Packt offers eBook versions of every book published, with PDFand ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy.Get in touch with us at service@packtpub.com for more details.At www.PacktPub.com, you can also read a collection of free technical articles, signup for a range of free newsletters and receive exclusive discounts and offers on Packtbooks and eBooks.TMhttp://PacktLib.PacktPub.comDo you need instant solutions to your IT questions? PacktLib is Packt's online digitalbook library. Here, you can access, read and search across Packt's entire library ofbooks.Why Subscribe? Fully searchable across every book published by Packt Copy and paste, print and bookmark content On demand and accessible via web browserFree Access for Packt account holdersIf you have an account with Packt at www.PacktPub.com, you can use this to accessPacktLib today and view nine entirely free books. Simply use your login credentials forimmediate access.

Table of ContentsPrefaceChapter 1: Angular ZenMeet AngularJSGetting familiar with the frameworkFinding your way in the projectThe communityOnline learning resourcesLibraries and extensionsToolsBatarangPlunker and jsFiddleIDE extensions and pluginsAngularJS crash courseHello World – the AngularJS exampleTwo-way data binding178889999101010101012The MVC pattern in AngularJS12Modules and dependency injection26AngularJS and the rest of the worldjQuery and AngularJS3839A sneak peek into the futureSummary4141Bird's eye viewScopes in depthViewModules in AngularJSCollaborating objectsRegistering servicesModules lifecycleModules depending on other modulesApples and oranges131521262729333540

Table of ContentsChapter 2: Building and TestingIntroducing the sample applicationGetting familiar with the problem domainTechnical stackPersistence storeMongoLabServer-side environmentThird-party JavaScript librariesBootstrap CSSBuild systemBuild system principles4344444546464748484849Automate everythingFail fast, fail cleanDifferent workflows, different commandsBuild scripts are code too49495050Tools50Grunt.jsTesting libraries and toolsJasmineKarma runner51515152Organizing files and foldersRoot foldersInside the source folder525254File-naming conventionsAngularJS modules and filesOne file, one moduleInside a module57575859Automated testingUnit tests6263End-to-end tests70AngularJS specific filesStart simpleInside the test folder545657Different syntax for registering providersSyntax for declaring the configure and run blocksAnatomy of a Jasmine testTesting AngularJS objectsTesting servicesTesting controllersMock objects and asynchronous code testingDaily workflowKarma runner tips and tricksExecuting a subset of testsDebugging5961646565676871727373Summary74[ ii ]

Table of ContentsChapter 3: Communicating with a Back-end ServerMaking XHR and JSONP requests with httpGetting familiar with the data model and MongoLab URLs http APIs quick tourThe configuration object primerRequest data conversionDealing with HTTP responsesResponse data conversionDealing with same-origin policy restrictionsOvercoming same-origin policy restrictions with JSONPJSONP limitationsOvercoming same-origin policy restrictions with CORSServer-side proxies75757676777879797980818183The promise API with qWorking with promises and the q service8485 q integration in AngularJSThe promise API with httpCommunicating with RESTful endpointsThe resource service93949595Learning q service basicsPromises are first-class JavaScript objectsAggregating callbacksRegistering callbacks and the promise lifecycleAsynchronous action chainingMore on qConstructor-level and instance-level methods resource creates asynchronous methodsLimitations of the resource serviceCustom REST adapters with httpUsing advanced features of httpIntercepting responsesTesting code that interacts with httpSummaryChapter 4: Displaying and Formatting DataReferencing directivesDisplaying results of expression evaluationThe interpolation directiveRendering model values with ngBindHTML content in AngularJS expressionsConditional displayIncluding blocks of content conditionallyRendering collections with the ngRepeat directiveGetting familiar with the ngRepeat directive[ iii 1111112114114115

Table of ContentsSpecial variablesIterating over an object's propertiesngRepeat patternsLists and detailsAltering tables, rows, and classesDOM event handlersWorking effectively with DOM-based templatesLiving with verbose syntaxngRepeat and multiple DOM elementsElements and attributes that can't be modified at runtimeCustom HTML elements and older versions of IEHandling model transformations with filtersWorking with built-in filtersFormatting filtersArray-transforming filtersWriting custom filters – a pagination exampleAccessing filters from the JavaScript codeFilters dos and don'tsFilters and DOM manipulationCostly data transformations in filtersUnstable filtersSummaryChapter 5: Creating Advanced FormsComparing traditional forms with AngularJS formsIntroducing the ngModel directiveCreating a User Information FormUnderstanding the input directivesAdding the required validationUsing text-based inputs (text, textarea, e-mail, URL, number)Using checkbox inputsUsing radio inputsUsing select inputsProviding simple string optionsProviding dynamic options with the ngOptions directiveUsing empty options with the select directiveUnderstanding select and object equivalenceSelecting multiple optionsWorking with traditional HTML hidden input fieldsEmbedding values from the serverSubmitting a traditional HTML formLooking inside ngModel data bindingUnderstanding ngModelControllerTransforming the value between the model and the view[ iv 146148149150150150151151151152

Table of ContentsTracking whether the value has changedTracking input field validity152153Validating AngularJS formsUnderstanding ngFormControllerUsing the name attribute to attach forms to the scopeAdding dynamic behavior to the User Information FormShowing validation errorsDisabling the save button153153154154155156Disabling native browser validationNesting forms in other formsUsing subforms as reusable componentsRepeating subformsValidating repeated inputsHandling traditional HTML form submissionSubmitting forms directly to the serverHandling form submission events157157157158159161161161Resetting the User Info formSummary162164Using ngSubmit to handle form submissionUsing ngClick to handle form submissionChapter 6: Organizing NavigationURLs in single-page web applicationsHashbang URLs in the pre-HTML5 eraHTML5 and the history APIUsing the location serviceUnderstanding the location service API and URLsHashes, navigation within a page, and anchorScrollConfiguring the HTML5 mode for URLsClient sideServer sideHandcrafting navigation using the location serviceStructuring pages around routesMapping routes to URLsDefining controllers in route partialsThe missing bits in the handcrafted navigationUsing built-in AngularJS routing servicesBasic routes definitionDisplaying the matched route's 74174175175175176Matching flexible routes177Reusing partials with different controllersAvoiding UI flickering on route changes178179Defining default routesAccessing route parameter values[v]178178

Table of ContentsPreventing route changesLimitations of the route serviceOne route corresponds to one rectangle on the screen181182183No nested routes supportRouting-specific patterns, tips, and tricksHandling links184185185Handling multiple UI rectangles with ng-includeCreating clickable linksWorking with HTML5 and hashbang mode links consistentlyLinking to external pagesOrganizing route definitionsSpreading route definitions among several modulesFighting code duplication in route definitionsSummaryChapter 7: Securing Your ApplicationProviding server-side authentication and authorizationHandling unauthorized accessProviding a server-side authentication APISecuring partial templatesStopping malicious attacksPreventing cookie snooping (man-in-the-middle attacks)Preventing cross-site scripting attacksSecuring HTML content in AngularJS expressionsAllowing unsafe HTML bindingsSanitizing 95195196196Preventing the JSON injection vulnerabilityPreventing cross-site request forgeryAdding client-side security supportCreating a security serviceShowing a login formCreating security-aware menus and toolbars197198198199200201Supporting authentication and authorization on the clientHandling authorization failuresIntercepting responses203203204Hiding the menu itemsCreating a login toolbarHTTP response interceptorsCreating a securityInterceptor serviceCreating the securityRetryQueue serviceNotifying the security servicePreventing navigation to secure routesUsing route resolve functions[ vi ]201202204205207208208209

Table of ContentsCreating the authorization serviceSummaryChapter 8: Building Your Own DirectivesWhat are AngularJS directives?Understanding the built-in directivesUsing directives in the HTML markupFollowing the directive compilation life-cycleWriting unit tests for directivesDefining a directiveStyling buttons with directivesWriting a button directiveUnderstanding AngularJS widget directivesWriting a pagination directiveWriting tests for the pagination directiveUsing an HTML template in a directiveIsolating our directive from its parent scopeInterpolating the attribute with @Binding data to the attribute with Providing a callback expression in the attribute with 26227227Implementing the widgetAdding a selectPage callback to the directiveCreating a custom validation directiveRequiring a directive controller228229230231Working with ngModelControllerWriting custom validation directive testsImplementing a custom validation directiveCreating an asynchronous model validatorMocking up the Users serviceWriting tests for asynchronous validationImplementing the asynchronous validation directiveWrapping the jQueryUI datepicker directiveWriting tests for directives that wrap librariesImplementing the jQuery datepicker aking the controller optionalSearching for parents for the controllerChapter 9: Building Advanced DirectivesUsing transclusionUsing transclusion in directivesTranscluding into an isolated scope directive[ vii ]231232245245245246

Table of ContentsCreating an alert directive that uses transclusionUnderstanding the replace property in the directive definitionUnderstanding the transclude property in the directive definitionInserting the transcluded elements with ng-transcludeUnderstanding the scope of transclusionCreating and working with transclusion functionsCreating a transclusion function with the compile serviceCloning the original elements when transcluding246247248248248250251251Accessing transclusion functions in directives252Creating an if directive that uses transclusion253Getting the transclusion function in the compile function with transcludeFnGetting the transclusion function in the directive controller with transcludeUsing the priority property in a directiveUnderstanding directive controllersInjecting special dependencies into directive controllersCreating a controller-based pagination directiveUnderstanding the difference between directivecontrollers and link functionsInjecting dependenciesThe compilation processAccessing other controllersAccessing the transclusion functionCreating an accordion directive suiteUsing a directive controller in accordionImplementing the accordion directiveImplementing the accordion-group directiveTaking control of the compilation processCreating a field directiveUsing the terminal property in 63263265265267Using the interpolate service268Loading templates dynamicallySetting up the field templateSummary269270271Binding to validation messages269Chapter 10: Building AngularJS Web Applicationsfor an International AudienceUsing locale-specific symbols and settingsConfiguring locale-specific modulesMaking use of available locale settingsLocale-specific settings and AngularJS filtersHandling translationsHandling translated strings used in AngularJS templatesUsing filtersUsing directives[ viii ]273274274275275276277278279

Table of ContentsHandling translated strings used in the JavaScript codePatterns, tips, and tricksInitializing applications for a given locale280282282Switching localesCustom formatting for dates, numbers, and currenciesSummary284285287Consequences of including locales as part of URLsChapter 11: Writing Robust AngularJS Web ApplicationsUnderstanding the inner workings of AngularJSIt is not a string-based template engineUpdating models in response to DOM eventsPropagating model changes to the DOMSynchronizing DOM and modelScope. apply – a key to the AngularJS worldPutting it all togetherPerformance tuning – set expectations, measure, tune, and repeatPerformance tuning of AngularJS applicationsOptimizing CPU utilizationSpeeding up digest loopsEntering the digest loop less frequentlyLimit the number of turns per digest ptimizing memory consumption312The ng-repeat directive314Avoid deep-watching whenever possibleConsider the size of expressions being watchedCollection watching in ng-repeatMany bindings made easy312314314315SummaryChapter 12: Packaging and Deploying AngularJSWeb ApplicationsImproving network-related performanceMinifying static resourcesHow does AngularJS infer dependencies?Writing minification-safe JavaScript codeThe pitfalls of array-style DI annotationsPreloading templatesUsing the script directive to preload templatesFilling in the templateCache serviceCombining different preloading techniquesOptimizing the landing pageAvoid displaying templates in their unprocessed formHiding portions of the DOM with ng-cloakHiding individual expressions with ng-bindIncluding AngularJS and application scripts[ ix ]315317318318318319322323324325327327328328329330

Table of ContentsReferencing scriptsAngularJS and Asynchronous Module DefinitionSupported browsersWorking with Internet ExplorerSummaryIndex330331333333334337[x]

PrefaceAngularJS is a relatively new JavaScript MVC framework but it is the real gamechanger. It has a novel approach to templating and bi-directional data bindingwhich makes the framework very powerful and easy to use. People constantlyreport a dramatic reduction in the number of lines of code needed in applicationsusing AngularJS as compared to other approaches.AngularJS is an outstanding piece of engineering. With its strong emphasis on testingand code quality it promotes good practices for the entire JavaScript ecosystem. Giventhe quality and novelty of the technology, it is not surprising to see that many peopleare attracted to the framework, creating a very vibrant and supportive communityaround AngularJS, which contributes to its growing popularity.As AngularJS becomes more and more popular, people will start to use itin complex projects. But you will soon face problems that are not solved inthe standard documentation or in the simple examples found on the Web.AngularJS, as any other technology, has its own set of idioms, patterns, andbest practices that have been uncovered by the community, based on theircollective experiences.This is where this book comes in – it aims to show how to write non-trivial AngularJSapplications in a canonical way. Instead of describing how the framework works,this book focuses on how to use AngularJS to write a complex web application. Itprovides real answers to real questions being asked by the AngularJS community.In short, this is a book written for application developers, by application developers,and based on real developers questions. In this book you will learn: How to build a complete, robust application using existing AngularJSservices and directives.

Preface How to extend AngularJS (directives, services, filters) when there is no outof-the-box solutionHow to set up a high quality AngularJS development project (codeorganization, build, testing, performance tuning)What this book coversChapter 1, Angular Zen, serves as an introduction to AngularJS framework and theproject. The first chapter outlines project's philosophy, its main concepts, and basicbuilding blocks.Chapter 2, Building and Testing, lays a foundation for a sample application used in thisbook. It introduces problem domain and covers topics such as testing and buildingbest practices for the system.Chapter 3, Communicating with a Back-end Server, teaches us how to fetch data froma remote back-end and feed those data effectively to the UI powered by AngularJS.This chapter has extensive coverage of the promise API.Chapter 4, Displaying and Formatting Data, assumes that data to be displayed werealready fetched from back-end and shows how to render those data in the UI. Thischapter discusses the usage of AngularJS directives for UI rendering and filters fordata formatting.Chapter 5, Creating Advanced Forms, illustrates how to allow users to manipulatedata through forms and various types of input fields. It covers various input typessupported by AngularJS and contains deep dive into forms validation.Chapter 6, Organizing Navigation, shows how to organize individual screens into aneasy-to-navigate application. It starts by explaining role of URLs in single-page webapplications and familiarizes a reader with key AngularJS services for managingURLs and navigation.Chapter 7, Securing Your Application, goes into the details of securing single-page webapplications written using AngularJS. It covers the concepts and techniques behindauthenticating and authorizing users.Chapter 8, Building Your Own Directives, serves as an introduction to one of themost exciting parts of the AngularJS: directives. It will guide the reader througha structure of sample directives as well as demonstrate testing approaches.Chapter 9, Building Advanced Directives, is based on Chapter 8, Building Your OwnDirectives and covers more advanced topics. It is filled with a real-life directiveexamples clearly illustrating complex techniques.[2]

PrefaceChapter 10, Building AngularJS Web Applications for an International Audience, dealswith internationalization of AngularJS applications. Covered topics includeapproaches to translating templates as well as managing locale-dependent settings.Chapter 11, Writing Robust AngularJS Web Applications focuses on non-functional,performance requirements for web applications. It peeks under the hood of AngularJSto familiarize readers with its performance characteristics. A good understanding ofAngularJS internals will allow us to avoid common performance-related pitfalls.Chapter 12, Packaging and Deploying AngularJS Web Applications will guide you througha process of preparing a finished application for production deployment. It illustrateshow to optimize application load with a special focus on the landing page.What you need for this bookTo experiment with AngularJS examples all you need is a web browser and a texteditor (or your favorite IDE). But in order to take full advantage of this book wewould recommend installing node.js (http://nodejs.org/) and its npm packagemanager with the following modules: Grunt (http://gruntjs.com/) Karma runner (http://karma-runner.github.io)Code examples illustrating interactions with a back-end are making use of acloud-hosted MongoDB database (MongoLab) so a working internet connectionis needed to run many examples from this book.Who this book is forThis book will be mostly useful to developers who are evaluating or have decidedto use AngularJS for a real-life project. You should have some prior exposure toAngularJS, at least through basic examples. We assume that you've got workingknowledge of HTML, CSS, and JavaScript.ConventionsIn this book, you will find a number of styles of text that distinguish betweendifferent kinds of information. Here are some examples of these styles, and anexplanation of their meaning.Code words in text are shown as follows: "We can include other contexts throughthe use of the include directive."[3]

PrefaceA block of code is set as follows:angular.module('filterCustomization', []).config(function ( provide) {varcustomFormats {'fr-ca': {'fullDate': 'y'}};When we wish to draw your attention to a particular part of a code block, therelevant lines or items are set in bold: head meta charset "utf-8" script src "/lib/angular/angular.js" /script script src "/lib/angular/angular-locale % locale % .js" /script base href "/ % locale % /" New terms and important words are shown in bold. Words that you see on thescreen, in menus or dialog boxes for example, appear in the text like this: "clickingthe Next button moves you to the next screen".Warnings or important notes appear in a box like this.Tips and tricks appear like this.Reader feedbackFeedback from our readers is always welcome. Let us know what you think aboutthis book—what you liked or may have disliked. Reader feedback is important forus to develop titles that you really get the most out of.To send us general feedback, simply send an e-mail to feedback@packtpub.com,and mention the book title via the subject of your message.If there is a topic that you have expertise in and you are interested in either writingor contributing to a book, see our author guide on www.packtpub.com/authors.[4]

PrefaceCustomer supportNow that you are the proud owner of a Packt book, we have a number of things tohelp you to get the most from your purchase.Downloading the example codeYou can download the example code files for all Packt books you have purchasedfrom your account at http://www.packtpub.com. If you purchased this bookelsewhere, you can visit http://www.packtpub.com/support and register

Pawel strongly believes in free, open source software. He has been very committed in the AngularJS project and also is very active in the AngularJS community. He also contributes to Angular UI – the companion suite to the AngularJS framework, where he focuses on the Twitt