The role of the UI
Making Plugins
Popular UI Libraries, Tools and Plugins
Debugging & Testing
The HTML Template
How the scope interacts with the template
Directives
Animations
Simple Template code
Composeable Directives
Using the right tool for the job
Small / Loose controllers
Bad UI involves coupling
Terse HTML template code
Abusing the scope
Fat controllers
The UI is all about directives
Directives should extend HTML
Separate Data from Function
Use directives as best possible
Let's create a validation example
Split the code between data and function
Follow this method always with code
Let's create a tic-tac-toe example
<div ng-controller="TicTacToeCtrl">
<div ng-repeat="row in rows">
<div ng-repeat="col in row.cols">
{{ col }}
</div>
</div>
</div>
.controller('TicTacToeCtrl', function($scope) {
$scope.rows = [
{ cols : [ 1, 2, 3 ] },
{ cols : [ 4, 5, 6 ] },
{ cols : [ 7, 8, 9 ] }
];
});
Pro: Simple HTML Code
Con: Scope data is form-fitted
Con: Code is too terse
Con: Unable to extend
.directive('ticTacToe', function(createMatrix) {
return {
controller : function($scope, $attrs) {
var rows = $scope.$eval($attrs.ticTacToe);
$scope.rows = createMatrix(rows);
},
template : '<div ng-repeat="row in rows">' +
' <div ng-repeat="col in row.cols">' +
' {{ col }}' +
' </div>' +
'</div>'
}
});
<div ng-controller="TicTacToeCtrl"
tic-tac-toe="rows"></div>
.controller('TicTacToeCtrl', function($scope) {
$scope.rows = [
1, 2, 3,
4, 5, 6,
7, 8, 9
];
});
Pro: Compact HTML Code
Con: Mix of JS and HTML code
Con: No real benefit
<div ng-controller="TicTacToeCtrl"
tic-tac-toe="9">
{{ cells[index] }}
</div>
.controller('TicTacToeCtrl', function($scope) {
$scope.cells = [
1, 2, 3,
4, 5, 6,
7, 8, 9
];
});
.directive('ticTacToe', function() {
return {
transclude : 'element',
terminal : true,
link : function($scope, $element, $attrs, ctrl, transcludeFn) {
var cells = $scope.$eval($attrs.ticTacToe);
var anchor = $element;
for(var i=0;i<cells.length;i++) {
var scope = $scope.$new();
scope.index = i;
transcludeFn(scope, function(element) {
element.after(anchor);
anchor = element;
});
}
},
};
});
Pro: High-level language
Pro: Simple Scope Data
Con: Complexity of the directive
Separate Construction from Data
Isolate the construction into a directive
Angular keeps improving
Use the most modern features
Tutorials may be expired
Patterns emerge
Use the template to drive communication
Use controllerAs
Or use directives with controllers
.controller('CommentCtrl', function() {
this.content = comment.content;
this.date = comment.date;
this.destroy = function() {
//remove the comment
}
});
<div ng-controller="CommentCtrl as comment"></div>
.directive('commentCtrl', function() {
return {
controller : function($scope, $attrs) {
this.content = comment.content;
this.date = comment.date;
this.destroy = function() {
//remove the comment
}
$scope[$attrs.as] = this;
}
}
});
<div comment-ctrl as="comment"></div>
Let's create a multi-level form example
.controller('FormCtrl', function($scope) {
//One Big Fat Ctrl
})
<form ng-controller="FormCtrl">
...
</form>
Pro: Simple HTML
Con: Fat Controllers
Con: Breaks the Law of Demeter
.controller('FormCtrl', function($scope) {
})
.controller('SubFormCtrl', function($scope, $attrs) {
var color = $scope.$eval($attrs.color);
})
<form ng-controller="FormCtrl">
...
<div ng-controller="ColorFormCtrl" color="color">
</div>
</form>
Pro: More Isolation
Con: Strict Inheritance
Con: Weird naming conventions
<form ng-controller="FormCtrl as form">
...
<div ng-controller="ColorFormCtrl as colorForm" color="color">
</div>
</form>
Pro: Communication in the template
Con: Verbose Controller Attributes
<form form-ctrl as="form">
...
<div color-form-ctrl="color" as="colorForm">
</div>
</form>
Pro: Inheritance in the template and directive
Con: Obscure JS code
best level of flexibility
access to controller and DOM
isolation of the controller
requiring other controllers
Use a proper naming convention
Store everything inside of one module
Expose all template code as custom directives
CSS classes/code should have a naming convention as well
my-plugin/
plugin.html
plugin.css
plugin.js
Bower
ngmodules.org
UI Libraries
Breeze & Restangular
RequireJS & Browserify
AngularUI
Angular-Strap
KendoUI
Difficult to find something good
Updated Frequently
Native-Angular code
Might not be compatible with non-angular code
Uses its own animation code
Acts as a passthrough with Angular
Bootstrap is independent
Uses ngAnimate
Pricing model
Mobile Support
Wider selection of widgets
Angular integration mixed
Use debugger or breakpoints
Hope into the console
Use angular.element() to gain access
Easy to test code when the structure is separate
Reduce the overall template footprint
Karma has some tricks you can use