This is part 2 of our series. Click here if you need to read part 1.
Now that we have our project set up, we can start building our application.
This post contains a number of templates you can use to start hacking away.
Module
/* To ensure other modules your app depends on loads before your app,
* ensure you have these amd-dependecy special comments at the top.
* This loads them without actually importing them.
*
* Be sure to export your module, so you can register components on it
* later.
*/
/// <amd-dependency path="ui-router" />
/// <amd-dependency path="ui-bootstrap" />
import {module} from "angular";
export var app: angular.IModule = module("app", [
"ui-router",
"ui-bootstrap"
]);
Controller
/* We can use classes as controllers. These classes can also work as
* controllers for directives.
*/
import {controller, IHttpService, IScope} from "angular";
import {app} from "../app.module";
// If we want things on the $scope, we need to make a custom scope interface
// that extends the default.
IAppScope extends IScope {
disabled: boolean
}
// export the class so we can import it into our unit tests
export class AppController {
// To inject dependencies, use the $inject syntax
public static $inject: Array<string> ["$scope", "$http"];
// Put whatever you're binding on your views in the public space
public user: string;
// Be sure to save references to injected services if you need access to them
// outside the constructor
private $http: IHttpService;
private $scope; IAppScope;
constructor($scope: IAppScope, $http: IHttpService) {
$scope.disabled = true;
this.$scope = $scope;
this.$http = $http;
$http.get("http://example.com/myresource").then((data: string) => {
this.user = data;
$scope.disabled = true;
});
}
}
app.controller("AppController", AppController);
Directive
import {IDirective} from "angular";
import {app} from "../app.module";
app.directive("myDirective", MyDirective.Factory);
// Now we can even extend our directive if we want to inherit from it.
class MyDirective {
public restrict: string = "E";
public controller: MyDirectiveController = MyDirectiveController;
public controllerAs: string = "vm";
public static Factory(): IDirective {
return new this();
}
}
export class MyDirectiveController {
// ...
}
Service
import {IHttpService} from "angular";
import {app} from "../app.module";
// Make sure to make interfaces of any models you're getting.
export interface IJsonPlaceHolderPost {
userId: number;
title: string;
body: string;
}
// Much like classes, services are new'd up, so we can use regular classes
// Export the service so we can import it into our unit tests later.
export class MyService {
public static $inject = ["$http"];
private $http: angular.IHttpService
constructor($http: angular.IHttpService) {
this.$http = $http;
}
public getPost(id: number): angular.IHttpPromise<IJsonPlaceholderPost> {
return this.$http.get(`http://jsonplaceholder.typicode.com/posts/${id}`);
}
}
app.service("myService", MyService);
Factory
import {IWindowService} from "angular";
import {app} from "../app.module";
export interface IUserInfo {
username: string;
token: string;
fullName: string;
}
// This time we use a factory pattern to create the service.
export class MyService {
public userInfo: IUserInfo;
constructor(userInfo: IUserInfo) {
this.userInfo = userInfo;
}
public static factory($window: IWindowService) {
var userInfo: IUserInfo = JSON.parse<IUserInfo>($window.localStorage.userInfo);
return new this(userInfo);
}
}
MyService.factory.$inject = ["$window"];
app.factory("myService", MyService.factory);
Provider
The biggest difference here is that we can configure a provider during any
angular config
calls, such as injecting an API endpoint.
import {IHttpService, IServiceProvider} from "angular";
import {app} from "../app.module";
export interface IUserInfo {
username: string;
token: string;
fullName: string;
}
export class MyServiceProvider extends IServiceProvider {
public static endpoint: string;
constructor() {
this.$get.$inject = ["$http"];
}
public $get($http: IHttpService): MyService {
return new MyService($http, MyServiceProvider.endpoint);
}
}
export class MyService {
private $http: IHttpService;
private endpoint: string;
constructor($http: IHttpService, endpoint: string) {
this.$http = $http;
this.endpoint = endpoint;
}
public getUserInfo(user: string) {
this.$http.get(`${this.endpoint}/users/${user}`);
}
}
angular.provider("MyService", MyServiceProvider);