On Github arilaen / angular-intro-gdi
Girl Develop It is here to provide affordable and accessible programs to learn software through mentorship and hands-on instruction.
Some "rules"
Tell us about yourself.
For coding at home, a text editor (Atom, Sublime Text)
index.html
<body ng-app="app"> <p>2 + 2 = {{2 + 2}}</p> </body>
View components and logic
angular.module('app', []).directive('myTooltip', myTooltipFn);
<my-tooltip></my-tooltip>
<div my-tooltip="options"></div>
index.html
<body ng-app="app"> <h1>{{pageTitle}}</h1> </body>
<button ng-if="changesEnabled">Edit</button>
Two way data binding!
<input type="text" ng-model="name"/> Name: {{name}}
<a href="" ng-click="openModal()">See details</a>
Start Date: <input ng-change="updateMinDate()" type="text" uib-datepicker/>
<table> <tbody> <tr ng-repeat="account in accounts track by $index"> <td ng-bind="account.name"></td> </tr> </tbody> </table>
View logic and scope
Use with ng-controller directive, ng-view, or ui-view (with UI-Router - more on this later!)
app.js
angular.module('app', []) .controller("menuController", ['$scope', function($scope) { $scope.pageTitle = "Angular Example Site"; }]);
index.html
<!DOCTYPE html><html ng-app> <head><title>{{pageTitle}}</title></head> <body> <div ng-controller="menuController"> <h1>{{pageTitle}}</h1> </div> <script src="./app.js"> </body> </html>
app.js
angular.module('app', []) .controller("menuController", ['$scope', function($scope) { this.pageTitle = "Angular Example Site"; }]);
index.html
<!DOCTYPE html><html ng-app> <head><title>{{pageTitle}}</title></head> <body> <div ng-controller="menuController as menuCtrl"> <h1>{{menuCtrl.pageTitle}}</h1> </div> <script src="./app.js"> </body> </html>
<table ng-controller="accountController as accountCtrl"> <thead>...</thead> <tbody> <tr ng-repeat="account in accounts track by $index"> <td ng-bind="account.name"></td> </tr> </tbody> </table>
{{ name | uppercase }}
Sam -> SAM
{{ startDate | date:'MM/dd/yyyy' }}
new Date() -> 04/26/2016
<table ng-controller="accountController as accountCtrl"> <th ng-repeat="tableLabel in accountCtrl.accountTableLabels"> {{tableLabel | uppercase}}</th> <tbody> <tr ng-repeat="account in accounts track by $index | accountCtrl.balanceOverZero"> <td ng-bind="account.name"></td> </tr> </tbody> </table>
app.js
angular.module('app', []).service("menuService", function() { this.pageTitle = "Angular Example Site"; }) .controller("menuController", ['$scope', 'menuService', function($scope, menuService) { $scope.pageTitle = "Angular Example Site"; }]);
index.html
<!DOCTYPE html> <html ng-app><head><title>{{pageTitle}}</title></head> <body> <div ng-controller="menuController"> <h1>{{pageTitle}}</h1> </div> <script src="./app.js"> </body> </html>
Fork this codepen and use six directives you've learned: http://codepen.io/arilaen/pen/oxPwQq
Here's the list again (starred directives are required):
Questions/thoughts before we begin?
http://www.techstrikers.com/AngularJS/angularjs-mvc-pattern.php
https://plus.google.com/+AngularJS/posts/aZNVhj355G2
View components and logic
angular.module('app', []).directive('myTooltip', myTooltipFn);
Element style
<my-tooltip></my-tooltip>
Attribute style
<div my-tooltip="options"></div>
app.js
angular.module('app', []) .controller("menuController", ['$scope', function($scope) { this.pageTitle = "Angular Example Site"; }]);
index.html
<!DOCTYPE html><html ng-app> <head><title>{{pageTitle}}</title></head> <body> <div ng-controller="menuController as menuCtrl"> <h1>{{menuCtrl.pageTitle}}</h1> </div> <script src="./app.js"> </body> </html>
There are two types:
<profile-section></profile-section>
<input type="number" model="accountCtrl.percentGoal" percent-mask />
<ng-include="./profile-section-template.html"></ng-include>
angular.module('app', []).directive("profileSection", function() { return { restrict: 'E', //E for element, A for attribute!, templateUrl: './profile-section.html', scope: {}, transclude: true //Has access to everything in parent scope - avoid! } };
angular.module('app', []).directive("profileSection", function() { return { restrict: 'E', template: '<div class="profile-section"><h2>Profile</h2></div>', scope: {} } };
angular.module('app', []).directive("profileSection", function() { return { restrict: 'E', template: 'Name: {{name}}, Age: {{age}}', scope: { name: '=name', //or '=' age: '=age' //or '=' } } };
<table> <tbody> <tr ng-repeat="user in users"> <profileSection name="user.name" age="user.age"></profile-section> </tr> </tbody> </table>
Write your own directive in your codepen
Ideas:
You can add logic via a controller:
angular.module('app', []).directive("profileSection", function() { return { restrict: 'E', template: 'Name: {{name}}, Age: {{age}}', controller: 'ProfileController' // Angular manages dependencies and will find this with just a string! scope: { name: '=name', //or '=' age: '=age' //or '=' } } };
Or more commonly, with a link function (more on this next class):
angular.module('app', []).directive("", function() { return { restrict: 'A', template: 'Name: {{name}}, Age: {{age}}', scope: { firstName: '=' lastName: '=' }, link: function(scope, element, attributes) { scope.name = scope.firstName + ' ' + scope.lastName; } } };
'=' is for two way binding
'&' is for one way binding (usually functions)
'@' is for text
angular.module('app', []).directive("profileSection", function() { return { restrict: 'E', template: 'Name: {{name}}, Age: {{age}}', scope: { name: '=' age: '@' } } }; // <profile-section name="user.name" age="20"></profile-section>
Codepen review! http://codepen.io/arilaen/pen/oxPwQq
Making a service
angular.module('app', []).service("menuService", function() { this.pageTitle = "Angular Example Site"; }) .controller("menuController", ['$scope', 'menuService', function($scope, menuService) { $scope.pageTitle = "Angular Example Site"; }]);
index.html
<!DOCTYPE html> <html ng-app><head><title>{{pageTitle}}</title></head> <body> <div ng-controller="menuController"> <h1>{{pageTitle}}</h1> </div> <script src="./app.js"> </body> </html>
angular.module('app', []).service("todoService", ['$http', function($http) { var service = this; this.getTodos = $http.get('http://jsonplaceholder.typicode.com/todos'); this.todos = []; function init() { this.getTodos().then(function(data) { service.todos = data; }); } init(); }]);
angular.module('app', []) .service("todoService", todoService) .controller("todoController", ['$menuService', function($menuService) { this.todos = menuService.todos; }]);
Asynchronous vs. Synchronous Code
Most of your code is synchronous - runs sequentially
var data = [{id: 0, name: 1}];
console.log(data.name);
Asynchronous vs. Synchronous Code
Most of your code is synchronous - runs sequentially
var data = [{id: 0, name: 1}];
console.log(data.name);
For external calls, use promises and callbacks
$http.get('/posts').then(function(result) {...})
angular.module('app', []) .service("todoService", todoService) .controller("todoController", ['$menuService', function($menuService) { this.todos = menuService.todos; this.addTodo = menuService.addTodo; this.updateTodo = menuService.updateTodo; this.saveTodo = menuService.saveTodo; }]);
Let's put it all together and use services with a form, in codepen!
angular.module('app') .component('heroDetail', { templateUrl: 'heroDetail.html', controller: HeroDetailController, bindings: { hero: '=' } });
Allows us to define our own two-way data binding!
angular.module('app', []) .controller("todoController", ['$scope', function($scope) { $scope.hours = 10; $scope.cost = $scope.hours * 3; $scope.$watch(function(newValue, oldValue) { $scope.cost = $scope.hours * 3; }); }]);
Practice! Time to finish your trip apps! You can follow along with me here: http://codepen.io/arilaen/pen/oxPwQq