TechEd North America 2014, Houston
Building Rich Apps with AngularJS on ASP.NET – John Papa
Day 4, 15 May 2014, 8:30AM-9:45AM (DEV-B420)
Disclaimer: This post contains my own thoughts and notes based on attending TechEd North America 2014 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of either Microsoft, the presenters or the speakers.
Executive Summary—Sean’s takeaways
-
Some great tips for organizing AngularJS projects
- Organized based on modules
- Keep Controller code separate from View
- “Above the fold”—show interface for code at the top, without implementation
- HotTowel is good template for creating a new project
- SideWaffle.com also has a bunch of template for AngularJS objects
- Use design tools in Chrome to look at Javascript, data on wire, etc.
-
Use BreezeJS to do more involved CRUD apps
- Change management
- Dirty bit
- Work in Progress, persisting local data
- Persisting data locally really improves user experience
John Papa – Tech Evangelist, formerly of Microsoft
@john_papa
www.johnpapa.net
Why AngularJS works
- Results quickly
- But then you hit walls
- This session is—about getting past these walls
- 10 tips
Emotional roller coaster ride
- Not a smooth ride, need to get past bumps
Building large scale apps requires some planning
Demos can be found at
- https://github.com/johnpapa/ng-demos
- http://pluralsight.com/training/Courses/TableOfContents/build-apps-angular-breeze
- https://github.com/johnpapa/angular.breeze.storagewip
Agenda
- How components fit (basics)
- HotTowel
- Coding patterns
- Structuring your project
- Modularity
- Tracing data
- Exception Handling
- Rich Data
- Validation
- Local Storage / WIP
Important to know which thing you need
Tip 1 – Component hierarchy
- Module – sort of like namespace in .NET
- Routes to get to various views
-
Views / binding ($scope) / Controller
- $scope – data binding
-
In View, use Directives
- 3rd party widgets
- Like HTML tag in View
-
Controllers can have Factories
- Features to share across controllers
- Factory aka Service
- SOLID principles
View
- HTML
- Built-in AngularJS directives
Controller
- Goes in module
- Handles View’s needs
- Contains logic for the view (presentation)
$scope
- Data binding
Modules
- Create module
- Way to inject features into your application
- Bring in modules from other places
- Containers of related features
- Inject functionality into your app
Routes
- Wire up URLs to Views
- Defines app navigation
Directives
- ng-xxxx – angular directive
- Callbacks
- Extends HTML
- Javascript can stay in controller
- Encapsulate reusable widgets
Factories
- Basically, services
- Singleton instance, share code across controllers
- A controller’s best friend
- Controller, always get instance (new)
- Ideal for abstracting things like logger, local storage, etc.
Tip 2 – Jump-Start with HotTowel
- Easy way to get started, rather than looking at blank screen
Project template
- Layout – CSS and fonts should be there
- Angular in project
- Other commonly used scripts
- Starter Files – Controllers, Views, Services
HotTowel-Angular
Demo – HotTowel
- File|New ASP.NET Web, empty
- NuGet package manager
- HotTowel.Angular
- Gets dependent stuff
- Moment – date library
- FontAwesome – fonts
Tip 3 – Coding Patterns
Each component has one Job
- Shorter .js files
- Code always has interface and details
- Name of service at top
- Public portion with just list of functions
- “Above the fold”
AngularJS File Templates
- http://sidewaffle.com
- Create Angular Controller, Directive, etc.
- Very good templates
- WebStorm on Mac
Demo – SideWaffle
- Lots of great things in Add New Item
Tip 4 – Structuring Your Project
Guidelines for Organizing AngularJS
- L – Locating code is easy
-
I – Identify code at a glance
- E.g. Not “Factories.js”
-
F – Flat structure as long as we can
- Lot easier to find something in flat structure
- After 7-10 files in folder, create sub-folder
-
T – Try to stay DRY
- Don’t Repeat Yourself
Typical – folders by type, e.g. controllers, services, etc.
- But when project gets big, this gets unwieldy
-
Better to do it by Feature
- E.g. Dashboard, Person, etc.
- Easier to split out on multiple-person team
- If someone says you’re doing it wrong—they’re wrong
- Browser doesn’t care how you organize your code
Options for structuring your file
- By Type
- By Feature
- Combination
But be consistent
Tip 5 – Modularity
Modularity
- Iterative development
- Reusable components
- E.g. add new module, plug into main module
- Reusable components to assemble an app
Modules
- Containers of related features
- Modules can depend on other modules
Modules are Containers
- <html ng-app=”moduleName”>
- Module contains all of the supporting members for the associated feature
Categories of Dependencies
- Angular modules – e.g. routing
- Custom modules – things that you write
- 3rd party – e.g. bootstrap, Kendo
Example for a modular app
- Modules: Layout, Dashboard, widgets
- Share core configuration—put this in a Core module
- Drawing dependency chart for modules
Demo – Modularity
-
app.module.js – just lists the modules at the top that you need
- E.g. Dashboard, layout, widgets
-
E.g. avengers module
- avengers.module.js – defines angular.module and lists dependencies
- On GitHub, johnpapa/ng-demos
-
Each module has its own routes
- Use routehelper.configureRoutes
- Each module defines its own routes
-
Core module
- core.module.js – lists Angular and custom modules that it depends on
- config.js – general configuration stuff, like app name, etc.
- In core because all modules use this
-
Common module
- Defines module that is end of the chain, no dependencies, empty array []
Tip 6 – Tracing Data
Tracing the data calls ** slide **
- View – button press “Get Avengers”
- $scope – binds to Controller
- Controller calls Data Factory
- $http – Ajax
- Hits web service
- Note: Application is asynchronous, i.e. responsive while data is being retrieved
- Data Factory handles async response
-
When data comes back, you need to tell Angular that you got the data
- Angular digest cycle sees the data
- With $http, Angular knows when data returns, automatically triggers digest cycle
Demo – Tracing Data in the Browser
- avengers.js – gets data, uses .then for promise, indicating what to do when data comes back
- Using debugger in Chrome
Tip 7 – Exception handler
- One place to handle all exceptions
- Use toast to show errors
Catch and Handle all Exceptions
- Local and Remote logging
- Dev vs. Debug modes
- Consistency
Decorate the $exceptionHandler Service
- You add to built-in exception handling features
Demo – Exception Handling
- Look at exceptionHandler.js
Tip 8 – Rich Data: BreezeJS
- When you need more than just simple data
Why Use Rich Data?
- $http gives you basic access to data
-
After that, Breeze lets you
- Track changes, etc.
- Multiple views of the same object
-
Change data in one place, change flows to other places
- Propagate changes
Dirty entities
- Can do stuff like setting Enabled for widgets, based on dirty bit
Demo – BreezeJS
- Breeze can hit against various things, e.g. Mobile Service, EF
-
Breeze keeps track of changeset – added, modified, deleted
- Data not yet sync’d to database
- Breeze then saves data back to cloud, but only the stuff that’s changed
- Explicit sync
Tip 9 – Validation
- Do you validate changes on client for better user experience?
- When validation error occurs, show the user immediately
Model Validation
- Where does presentation logic belong?
-
Validating in HTML
- Appears in every view
- Push validation down into Model
- How do we validate?
Demo – validation
- data-z-validate in <input> or <select>
- If using EF, stuff like max length of field is in metadata
- Metadata, but also custom rules
Validation on the server is mandatory
- Always do it on the server
- But also do it on the client
Demo – Model Validation
- Validation rules free, out of the box
- Also maintaining a full list of all of the validation errors
- On New item, don’t yet show validation errors for unfilled fields
Tip 10 – Work in Progress with Local Storage
- Why risk losing changes?
Options for saving changes
- When user leaves page, you lose changes
- You can’t leave (popups)
-
Auto-save as user types
- Send to database
- Tons of network traffic
- Incomplete object?
- Use local storage
Demo – Work in Progress with Local Storage
- Note: “Updated WIP” (in Breeze)
- Start indicates dirty bit
- Data survives navigate to another page and back again
- Even survives browser restart
How it Works
- Export/Import
Sean Questions
- How would Angular fit in with MVC? Can they be used together? Does that make sense?
Do you have an example that has master details example (cru)d
Are you asking if I have John’s full example? These are just my notes from his talk. I don’t recall if he posted all of his code or not, but you could go to his web site to find out if it’s there.