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