name: inverse layout: true class: center, middle, inverse --- #AngularJS Framework for Web Applications .footnote[[angularjs.org](http://angularjs.org)] --- ## Web History --- layout: false .left-column[ ## Static pages ] .right-column[ ```xml
Mattias homepage
Welcome to my homepage
``` ] --- .left-column[ ## Static pages ## Generated pages ] .right-column[ ### perl ```perl $name = "Mattias"; print ""; print ""; print "
$name homepage
"; print "
Welcome to my homepage
"; print ""; print ""; ``` ### php ```php
homepage
Welcome to my homepage
``` ] --- .left-column[ ## Static pages ## Generated pages ## Javascript & DOM ] .right-column[ ```xml
Welcome to my homepage
``` - DOM Manipulation - Browser compatibility problems! ] --- .left-column[ ## Static pages ## Generated pages ## Javascript & DOM ## jQuery ] .right-column[ ```xml
Welcome to my homepage
``` - Powerful element selection - Browser compatibility handled by library - Same DOM manipulation ] --- template: inverse ## Web Applications .large-image[  ] --- ## AngularJS - Developed by Google - Active project with large eco-system - Supports modern browsers --- ## MVC - Model View Controller .large-image[  ] --- .left-column[ ## Model ] .right-column[ Entire model contained in a single javascript data structure. ```javascript $scope = { employeeName: "Mattias", company: "Net Insight AB" } ``` ] --- .left-column[ ## Model ## View ] .right-column[ "Extended" html with references to model ```html
{{company}}
Employee name:
Submit
``` ### Result .sample[
Net Insight AB
Employee name:
Submit
] ] --- .left-column[ ## Model ## View ## Controller ] .right-column[ Javascript code that populates the view and reacts to changes in it. ```javascript function myCtrl( $scope ) { $scope = { employeeName: "Mattias", company: "Net Insight AB" }; $scope.save_info = function() { console.log( $scope.employeeName ); }; } ``` ] --- template: inverse name: example1 # Example 1 # Angular watches the model --- ## Controller populates Model ```javascript function MyCtrl( $scope ) { $scope.name = "World"; $scope.Click = function() { alert( "Hello " + $scope.name ); } } ``` --- ## View ```html
{{name}}
Click me
```
Result
--- template: inverse # Example 2 # json data via http --- ## Request: ``` get "http://api.icndb.com/jokes/random" ``` ## Response: ```javascript { "type": "success", "value": { "id": 459, "joke": "Chuck Norris can solve the Towers of Hanoi in one move.", "categories": ["nerdy"] } } ``` --- # Controller ```javascript function MyCtrl( $scope, $http ) { $scope.FetchJoke = function() { $http.get( "http://api.icndb.com/jokes/random") .then( function(response) { $scope.data = response.data; }); } } ``` --- # Template ```html
Joke {{data.value.id}}
{{data.value.joke}}
Fetch joke
```
Result
--- template: inverse name: example3 # Example 3 # Iterating through an array --- ## Request ``` get http://api.icndb.com/jokes/random/3 ``` ## Response ```javascript { "type": "success", "value": [ { "id": 513, "joke": "Chuck Norris does not...", "categories": ["nerdy"] }, { "id": 156, "joke": "There is no such...", "categories": [] }, { "id": 249, "joke": "Maslow's theory...", "categories": [] } ] } ``` --- ## Controller ```javascript function MyCtrl( $scope, $http ) { $scope.FetchJokes = function() { $http.get( "http://api.icndb.com/jokes/random/3") .then( function(response) { $scope.data = response.data; }); } } ``` --- ## View ```html
Chuck Norris jokes
{{joke.id}}
{{joke.joke}}
Fetch jokes
```
Result
--- template: inverse # Example 4 # Showing stuff conditionally --- template: inverse # Custom directives ```html
``` ```html
This message can be collapsed
``` *Separation of concerns* --- template: inverse # Routes and views Entire application on one page but the url changes --- # Routes and views ```javascript .when("/ets/if/:interface/basic", { templateUrl: "ets.if.basic.tmpl.html", controller: "EtsIfBasicCtrl", }) ``` ```html
``` *Separation of concerns* --- template: inverse # Services Separate different parts of the codebase from each other using services *Separation of concerns* --- template: inverse # Testability Uses Dependency injection Includes mocks for core services --- template: inverse # Real world test --- ## IP Interfaces Request ``` POST /data/oam ``` ```javascript [ { "root": "ipconf.if.*", "entries": "name address.0.inet? address.0.netmask? " + "media.active media.current mtu" } ] ``` --- ## IP Interfaces Response ```javascript { "_success": true, "_errors": [], "ipconf": { "if": { "0": { "name": "eth-aux", "address": {}, "media": { "active": "link down", "current": "autoselect" }, "mtu": "1500" }, "1": { ... } } } } ``` .panel[ Response built by node **without understanding the contents of oam** ] --- # Code size Current web: **172k** mostly minified js Webapp: **146k** minified js Can gzip compress down to one third. Data per page is a lot smaller with AngularJS. --- # Development Effort - Powerful development and debugging environment - Quick turnaround time - Possible to write tests - Very little code - Fun! --- name: last-page template: inverse ## More info: [angularjs.org](http://angularjs.org) Instruction videos on [egghead.io](http://egghead.io) AngularJS Google+ group This presentation is available on https://github.com/mattiash/angular-presentation