Some time ago I heard about AngularJS at a client and what it could do. It sounded very promising but I didn’t have the time to look into it then.
Now that things are a bit calmer, I took the time to look at this framework and I must say: “this in combination with SharePoint Apps can be very promising.”
I followed a simple example, built it in plain HTML, then ported it to a SharePoint App. Here are all the steps.
What Is AngularJS?
AngularJS is a framework that extends the HTML vocabulary. HTML wasn’t built to handle dynamic views — with AngularJS you can build dynamic views and the framework is fully extensible to fit your needs.
The Basics
ng-app — defines the root scope from where the framework is “active”.
ng-controller — content under this node is managed by a JS class defined in your custom JavaScript file.
ng-repeat — unrolls a collection; AngularJS creates a new copy of the template element for each item.
AngularJS incorporates the basic principles of the MVC design pattern.
Example: Plain HTML Todo App
Without Angular directives:
<!DOCTYPE html>
<html>
<head>
<title>Things to do</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css" />
<script src="Libs/angular.js"></script>
<script src="todo.js"></script>
</head>
<body class="well">
<h1>Meligo's todo list</h1>
<ul class="unstyled">
<li><input type="checkbox">Item 1</li>
<li><input type="checkbox">Item 2</li>
<li><input type="checkbox">Item 3</li>
</ul>
<form>
<input>
<button class="btn btn-primary">Add</button>
</form>
</body>
</html>
With Angular directives:
<!DOCTYPE html>
<html ng-app="todoApp">
<head>
<title>Things to do</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css" />
<script src="Libs/angular.js"></script>
<script src="todo.js"></script>
</head>
<body class="well" ng-controller="AppCtrl">
<h1>{{userName}}'s todo list</h1>
<ul class="unstyled">
<li ng-repeat="item in items">
<input ng-model="item.done" type="checkbox">{{item.text}}
</li>
</ul>
<form>
<input>
<button class="btn btn-primary">Add</button>
</form>
</body>
</html>
The controller in todo.js:
var todoApp = angular.module('todoApp', ['ngResource']);
todoApp.controller('AppCtrl', function AppCtrl($scope) {
$scope.userName = 'Meligo';
var items = [
{ text: 'task 1', done: false },
{ text: 'task 2', done: true },
{ text: 'task 3', done: false }
];
$scope.items = items;
$scope.remaining = function () {
return items.reduce(function (count, item) {
return item.done ? count : count + 1;
}, 0);
};
$scope.add = function (newItem) {
items.push({ text: newItem.text, done: false });
newItem.text = '';
};
});
$scope is essentially your context — anything you put on it is accessible from the HTML template.
Porting to a SharePoint App
It’s essentially the same. In the PlaceHolderAdditionalPageHead:
<script type="text/javascript" src="../Scripts/angular.js"></script>
<script type="text/javascript" src="../Scripts/AngularDemoScript.js"></script>
<script type="text/javascript" src="../Scripts/angular-resource.js"></script>
In PlaceHolderMain (no <html> or <body> tags, so use divs):
<div ng-app="todoApp">
<div ng-controller="AppCtrl">
<h1>{{userName}}'s todo list</h1>
<ul class="unstyled">
<li ng-repeat="item in items">
<input ng-model="item.done" type="checkbox">{{item.text}}
</li>
</ul>
<panel>
<input>
<button class="btn btn-primary">Add</button>
</panel>
</div>
</div>
It works exactly the same. Toggle a checkbox and the bound value flips between true and false in real time — two-way binding in action.
I’ll try to turn this into a series. AngularJS + SharePoint Apps is genuinely powerful, and the MVC separation makes the code a lot cleaner.
More info at angularjs.org.