Roma @ IED
22 Maggio 2015
Creazione dello scheletro dell'applicazione
$ mkdir mysite
$ cd mysite
$ npm install static-server
static-server@2.0.0 node_modules/static-server
|__ file-size@0.0.5
|__ mime@1.3.4
|__ commander@2.8.1 (graceful-readlink@1.0.1)
|__ chalk@0.5.1 (ansi-styles@1.1.0, escape-string-regexp@1.0.3, supports-color@0.2.0, strip-ansi@0.3.0, has-ansi@0.1.0)
Se avete privilegi di amministratori potete installarlo globalmente:
sudo npm install -g static-server
Da terminale nella directory di progetto mysite:
$ ./node_modules/.bin/static-server .
* Static server successfully started.
* Serving files at: http://localhost:9080
* Press Ctrl+C to shutdown.
<-- [GET] /
--> 200 OK / (index.html) 1.03 KiB (10.417ms)
o (se installato globalmente):
$ static-server .
$ npm install bower
Per installare bower globalmente: sudo npm install -g bower
bower install angular angular-route angular-foundation foundation
% bower install angular angular-route angular-foundation foundation
bower cached git://github.com/angular/bower-angular.git#1.3.15
bower validate 1.3.15 against git://github.com/angular/bower-angular.git#*
bower cached git://github.com/angular/bower-angular-route.git#1.3.15
...
"./node_modules/.bin/bower install ..." se non installato globalmente
bower init
$ bower init
? name: mysite
? version: 0.1.0
? description: my angular + foundation website
? main file:
? what types of modules does this package expose?: globals
? keywords:
? authors: Luca Greco <luca.greco@alcacoop.it>
? license: MIT
? homepage:
? set currently installed components as dependencies?: Yes
? add commonly ignored files to ignore list?: Yes
? would you like to mark this package as private which prevents
it from being accidentally published to the registry?: Yes
...
...
{
name: 'mysite',
version: '0.1.0',
authors: [
'Luca Greco <luca.greco@alcacoop.it>'
],
description: 'my angular + foundation website',
moduleType: [
'globals'
],
license: 'MIT',
private: true,
ignore: [
'**/.*',
'node_modules',
'bower_components',
'test',
'tests'
],
dependencies: {
'angular-foundation': '~0.6.0',
'angular-route': '~1.3.15',
'angular': '~1.3.15',
foundation: '~5.5.2'
}
}
? Looks good?: Yes
Il primo passo e' sempre quello di creare lo scheletro della nostra applicazione AngularJS:
<!DOCTYPE html>
<html ng-app="mysite">
<head>
<meta name="viewport"
content="width=device-width">
<!-- TODO: includes scripts -->
<!-- TODO: includes stylesheets -->
</head>
<body ng-controller="SiteCtrl">
<!-- TODO: root site template -->
</body>
</html>
index.html
<head>
<!-- includes JS deps -->
<script src="bower_components/angular/angular.js">
</script>
<script src="bower_components/angular-route/angular-route.js">
</script>
<script src="bower_components/angular-foundation/mm-foundation-tpls.js">
</script>
<!-- includes app entrypoint module -->
<script src="app.js">
</script>
</head>
index.html
<body ng-controller="SiteCtrl">
<div class="row">
<div class="small-12 columns"
ng-include="'views/topnav.html'">
</div>
</div>
<div class="row" ng-view>
</div>
<div class="row">
<div class="small-12 columns"
ng-include="'views/footer.html'">
</div>
</div>
</body>
index.html
<nav class="top-bar">
TOP NAV HEADER
</nav>
<div class="footer">
FOOTER TEMPLATE
</div>
(function () {
var app = angular.module("mysite", [
// include angular-foundation nelle dipendenze
// allo scopo di importare le direttive:
// top-bar, toggle-top-bar e top-bar-section
"mm.foundation"
]);
app.controller("SiteCtrl", function () {
// TODO: expose site name & top nav links
});
)();
app.js
<top-bar>
<ul class="title-area">
<li class="name">
<h1><a href="#">{{ "TODO: BrandName" }}</a></h1>
</li>
<li toggle-top-bar class="menu-icon">
<a href="">Menu</a>
</li>
</ul>
<top-bar-section>
<ul class="right">
<li>
<a href="#/products">Products</a>
</li>
<li class="active">
<a href="#/about">About</a>
</li>
</ul>
</top-bar-section>
</top-bar>
views/topnav.html
Doc Reference: http://pineconellc.github.io/angular-foundation/
<head>
...
<link href="bower_components/foundation/css/normalize.css"
rel="stylesheet">
<link href="bower_components/foundation/css/foundation.css"
rel="stylesheet">
<link href="app.css" rel="stylesheet">
</head>
index.html
body {
background: #ededed;
}
nav.top-bar {
margin-bottom: 2em;
}
.footer {
background: #626262;
color: white;
padding: 8px;
}
app.css
in un nuovo file 'site-routing.js' creare un nuovo modulo Angular:
(function () {
var app = angular.module("siteRouting", ["ngRoute"]);
app.constant("siteConfig", {
siteName: "MyBrand",
topNavLinks: [
{ title: "News", url: "#/news" },
{ title: "Products", url: "#/products" },
{ title: "About", url: "#/about" }
]
});
})();
site-routing.js
...
<!-- includes app modules -->
<script src="site-routing.js"></script>
<script src="app.js"></script>
</head>
index.html
nel modulo mysite aggiungerne la dipendenza ed utilizzare il modulo siteRouting per effettuare il binding del siteName dall'oggetto di configurazione allo scope del template:
var app = angular.module("mysite", [
"mm.foundation",
// inclusione del modulo di configurazione del routing
"siteRouting"
]);
app.controller("SiteCtrl", SiteCtrl);
function SiteCtrl($scope, siteConfig) {
$scope.siteName = siteConfig.siteName;
});
app.js
All'interno del template relativo alla top-bar, effettuare il binding della variabile nello scope:
<ul class="title-area">
<li class="name">
<h1><a href="#">{{ siteName }}</a></h1>
</li>
<li toggle-top-bar class="menu-icon">
<a href="">Menu</a>
</li>
</ul>
views/topnav.html
In modo analogo possiamo effettuare l'injections dell'array dei link da inserire in top-bar nello scope:
app.controller("SiteCtrl", SiteCtrl);
function SiteCtrl($scope, siteConfig) {
$scope.siteName = siteConfig.siteName;
$scope.topNavLinks = siteConfig.topNavLinks;
});
app.js
E nella top-bar-section possiamo effettuarne il binding con i link alle sezioni del sito, con l'aiuto della direttiva ng-repeat:
<top-bar-section>
<ul class="right">
<li ng-repeat="item in topNavLinks">
<a href="{{ item.url }}">{{ item.title }}</a>
</li>
</ul>
</top-bar-section>
views/topnav.html
Nel file site-routing.js possiamo definire una nuova costante siteRoutes:
app.constant("siteRoutes", {
when: [{
routeUrl: "/about",
templateUrl: "views/route-about.html",
navLinkIndex: 2
}, {
routeUrl: "/products",
templateUrl: "views/route-products.html",
navLinkIndex: 1
}, {
routeUrl: "/products/:id",
templateUrl: "views/route-product-detail.html",
navLinkIndex: 1
}, {
routeUrl: "/news",
templateUrl: "views/route-news.html",
navLinkIndex: 0
}],
otherwise: {
redirectTo: "/about"
}
});
site-routing.js
e generate la configurazione del routing da tale oggetto, con l'aiuto dell'helper angular.forEach:
app.config(function ($routeProvider, siteRoutes) {
angular.forEach(siteRoutes.when, function (route) {
$routeProvider.when(route.routeUrl, route);
});
$routeProvider.otherwise(siteRoutes.otherwise);
});
site-routing.js
Gli attributi navLinkIndex nella costante siteRoutes hanno lo scopo di permetterci di associare la rotta corrente al relativo link nella top-bar:
app.controller("SiteCtrl", SiteCtrl);
function SiteCtrl($scope, siteConfig, $route) {
$scope.siteName = siteConfig.siteName;
$scope.topNavLinks = siteConfig.topNavLinks;
$scope.isTopNavLinkActive = function (index) {
return $route.current.navLinkIndex === index;
};
});
app.js
<top-bar-section>
<ul class="right">
<li ng-class="{ active: isTopNavLinkActive($index) }"
ng-repeat="item in topNavLinks">
<a href="{{item.url}}">{{ item.title }}</a>
</li>
</ul>
</top-bar-section>
views/topnav.html
Al seguente link troverete l'archivio contenente i sorgenti dell'esercizio, relativamente al primo stadio di completamento:
L'esame finale e' diviso in due parti:
un piccolo progetto realizzato in AngularJS, su cui si dovra' lavorare nelle settimane che precedono l'esame e consegnare almeno qualche giorno prima della prova orale.
una prova orale, durante la quale verranno valutate la comprensione dei concetti e componenti base di AngularJS (e di conseguenza Javascript), anche attraverso la discussione del progetto consegnato
Il progetto realizzato in AngularJS dovra':
Verranno considerate e valutate come bonus la presenza di una o piu' delle seguenti caratteristiche: