AngularJS新手进阶指南:从入门到专家

需积分: 10 1 下载量 35 浏览量 更新于2024-07-20 收藏 3.12MB PDF 举报
"AngularJS: Novice to Ninja" 是一本由 Sanjeev Panda 编著的深入指南,专为那些希望掌握这一流行的JavaScript框架的开发者设计。本书针对AngularJS的核心概念和技术进行了详尽讲解,帮助读者从初学者逐步成长为专业级的开发人员。AngularJS是一个开源框架,旨在简化大规模AJAX应用的开发过程,通过模块化、控制器、数据绑定、作用域和事件处理等功能提供高效开发环境。 第1章介绍读者如何入门AngularJS,激发对框架的兴趣。接下来,章节详细探讨了: - 模块、控制器与数据绑定:这部分教会读者如何组织代码并实现数据在页面上的自动更新。 - AngularJS作用域与事件:理解如何管理变量和控制DOM元素,以及如何利用Angular的事件系统。 - 多视图与路由:展示了如何创建动态内容切换和应用程序间的导航逻辑。 进一步深入,书中涵盖了: - 服务、工厂与提供者:讲解了如何封装可重用的功能和管理依赖关系。 - 开发单页博客应用:通过实际案例展示Angular在构建复杂应用中的应用。 - AngularJS表单处理:学习如何设计和验证用户输入,确保数据一致性。 - 与REST API交互:包括基本的HTTP请求、处理响应以及集成到应用中。 接着是: - REST API在单页博客中的应用:实战演示如何利用Angular的特性操作后端数据。 - AngularJS指令:扩展HTML功能,自定义组件的行为和指令。 - 添加评论系统:结合指令和数据绑定,构建交互式的评论模块。 - 依赖注入:理解如何管理和服务之间的依赖关系,提高代码可维护性。 - AngularJS过滤器:介绍如何格式化和转换数据,增强用户界面的呈现。 - AngularJS动画:探索如何使用动画效果提升用户体验。 最后部分涉及部署和国际化,以及: - Authentication and Authorization in AngularJS:确保安全,处理用户身份验证和访问权限控制。 版权信息强调了所有内容受保护,未经出版商书面许可,不得复制或传播。通过这本书,读者可以系统地学习和精通AngularJS,提升开发技能,应对现代Web开发的挑战。
2015-06-15 上传
非常不错的书 Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Who Should Read This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Conventions Used . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii Code Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii Tips, Notes, and Warnings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Supplementary Materials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Want to Take Your Learning Further? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx Chapter 1 Falling In Love With AngularJS . . . . . 1 The Power Features of AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Download and Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Installing via CDN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Hosting on Your Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Required Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 AngularJS Batarang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 The Angular Seed Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 The Anatomy of an AngularJS app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 What is MVW? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Structuring Our Code With MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Unit and End-to-End Testing in AngularJS . . . . . . . . . . . . . . . . . . . . . . . . 17 Where to Put Your Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 How to Run Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 When Not To Use AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Chapter 2 Modules, Controllers & Data Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Creating Our First Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Modular Programming Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 The Role of a Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Attaching Properties and Functions to Scope . . . . . . . . . . . . . . . . . . 30 Adding Logic to the Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Adding Instance Functions and Properties to Controllers . . . . . . . . 35 Dependency Injection in Controllers With Minification . . . . . . . . . 37 Overview of Two-Way Data Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 What Is Data Binding? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Two-Way Binding in AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Doing Something Cool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Introducing Our Demo Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 The Single Page Blogger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Getting Ready . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Chapter 3 AngularJS Scope & Events . . . . . . . . . . . . 45 Scope Demystified . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Writing Access with Prototypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 Objects Can Extend Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Prototypal Inheritance in AngularJS Scopes . . . . . . . . . . . . . . . . . . . . . . . 49 Advanced Scope Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 The Watchers in AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 The $watchCollection() Function . . . . . . . . . . . . . . . . . . . . . . . 56 The $apply() Function and the $digest Loop . . . . . . . . . . . . . . 57 $apply and $digest in Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 x Broadcasting & Emitting Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 $scope.$emit(name,args) For Emitting Events . . . . . . . . . . . . 64 $scope.$broadcast(name,args) For Broadcasting Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 $scope.$on(name,handlerFunction) For Registering Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Events in Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 The $destroy event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Chapter 4 Multiple Views and Routing . . . . . . . . . 71 Creating Multiple Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Using $routeParams in the Controller . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Using ng-template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 The resolve Property in the Route Config Object . . . . . . . . . . . . . . . . . 83 Exploring the $location Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 The API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Events in Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 $location related events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 $route related events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 The ng-include Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Introducing the Angular UI Router . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Getting Started With UI Routter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Defining States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Chapter 5 AngularJS Services, Factories, and Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 xi Eager Loading of a Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Factory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Constant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Using Decorators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Chapter 6 Developing Single Page Blogger . . . 113 Developing Our App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Defining Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Creating Our Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Creating the Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 Creating the Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 App Entry Point (index.html) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 How About Some Unit Tests? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Unit Testing postService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Unit Testing Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Writing an End-to-End (e2e) Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Chapter 7 Understanding AngularJS Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 AngularJS Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 <input> and <textarea> controls . . . . . . . . . . . . . . . . . . . . . . . 130 <select> control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 Radio Button Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 Checkbox Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 AngularJS Form Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 xii Applying Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 Updating Models With a Twist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 Forms in Action : Single Page Blogger v1.1 . . . . . . . . . . . . . . . . . . . . . . . 143 Creating the admin Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Defining States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Creating Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Admin Panel Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Template For Adding a New Post . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Chapter 8 Interacting with REST APIs . . . . . . . . . 151 A Primer on Promises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 The Promise API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Example Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Promise Chaining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Creating a Promise that Always Rejects . . . . . . . . . . . . . . . . . . . . . 159 Understanding the $http Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 The config Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 A Weather Search Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 Setting Request Headers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 Request and Response Transformers . . . . . . . . . . . . . . . . . . . . . . . . 166 Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Interceptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Understanding AngularJS $resource . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 How Does $resource Work? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 xiii Chapter 9 Using REST APIs in Single Page Blogger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Applying $resource to Our App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Defining Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Defining Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Including angular-resource.js and Adding the ngResource Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Unit Testing Our Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Chapter 10 AngularJS Directives . . . . . . . . . . . . . . . . . . 193 What Are Directives, Really? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 Directives From the jQuery Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Creating Custom Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 The Link Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 The Compile Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 Compilation of Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Changing a Directive’s Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Binding Between Parent Scope and Isolated Scope Models . . . . . . . . . 207 Using @ For One-Way Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Using = For Two-Way Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Using & to Execute Functions in the Parent Scope . . . . . . . . . . . . 209 Parent Scope vs. Child Scope vs. Isolated Scope . . . . . . . . . . . . . . . . . . . 212 Transclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Differences Between transclude:'element' and transclude:true . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 The Controller Function and Require . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Cleaning Up Your Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 IE 8 Precautions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 xiv Chapter 11 Adding a Comment System to Single Page Blogger . . . . . . . . . . . . . . . . . . . . 219 Unit Testing Our Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Chapter 12 Dependency Injection In AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 A Brief Recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 The $provide Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 The $injector Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 Dynamically Injecting a Dependency . . . . . . . . . . . . . . . . . . . . . . . . 230 Registration of Controllers, Filters, and Directives . . . . . . . . . . . . . 230 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 Chapter 13 AngularJS Filters . . . . . . . . . . . . . . . . . . . . . . . 233 Filter Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Fun with Custom Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Chaining Multiple Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Using Filters in Controllers, Services, and Directives . . . . . . . . . . . 236 Meet a Filter Called filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 Meet the orderBy Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Meet the limitTo Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Using the $filter Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Using Filters in Single Page Blogger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 Permalink Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 Wordcount Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 xv Chapter 14 AngularJS Animation . . . . . . . . . . . . . . . . . 245 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 Animation with CSS3 Transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 Going Further . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 Animation Using Keyframes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 Animation Using jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 Animation Using ngClass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 Animation with Custom Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Adding Simple Animation to Single Page Blogger . . . . . . . . . . . . . . . . . 257 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 Chapter 15 Deployment and Internationalization . . . . . . . . . . . . . . . . . . . 259 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Internationalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 Chapter 16 Authentication and Authorization in AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 Adding Login Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 Where To Go Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Things to Do Now . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Improving Our Demo App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 Host it Yourself : Back-end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283