// Controller using class
module App.Home {
interface IHomeViewModel {
title: string;
}
class HomeController implements IHomeViewModel {
title: string = "Welcome!!!";
static $inject = ["$location", "$rootScope"]
constructor(
private $location: ng.ILocationService,
private $rootScope: ng.IRootScopeService) {
}
}
angular.module("app")
.controller("homeController", HomeController);
}
In this example, an interface called IHomeViewModel
is created to represent the public members of the controller and a class HomeController
is created which implements the interface.
Dependencies are injected using static $inject
member and injected dependencies are declared as private members.
Here is an example of how we will add handler to Angular’s $routeChangeStart
event which is raised when route change is initiated
// Event handlers
private hookEventHandlers():void {
this.$rootScope.$on("$routeChangeStart", this.onRouteChangeStart);
}
private onRouteChangeStart():void {
console.log(this.title);
}
The hookEventHandlers method is called from the constructor of the controller which adds handler to $routeChangeStart
event and the handler simply logs title
member of the class into console.
When this method is run, you would expect it to show ‘Welcome!!!’ in the console but it shows undefined
instead.
This is happening because the caller of the method is NOT the instance of the class where it is defined, so this
doesn’t have a member named title
.
// Event handler using arrow function
private hookEventHandlers(): void {
this.$rootScope.$on("$routeChangeStart",() => {
this.onRouteChangeStart.call(this);
});
}
private onRouteChangeStart(): void {
console.log(this.title);
}
In this example, we have changed our event handler to be arrow function and the arrow function invokes onRouteChangeStart
using call function and passing current instance of the class where it is defined as this
reference.
But, how does arrow function has correct reference of this
? When arrow function is created, this
is lexically bound to the location where it is created. In this case, arrow function is created inside the member of a class where this
represents the current instance of the class. So this
reference inside the arrow function also represents the current instance of the class where it is created. That’s it :)
// Full code example
module App.Home {
interface IHomeViewModel {
title: string;
}
class HomeController implements IHomeViewModel {
title: string = "Welcome!!!";
static $inject = ["$location", "$rootScope"]
constructor(
private $location: ng.ILocationService,
private $rootScope: ng.IRootScopeService) {
this.hookEventHandlers();
}
private hookEventHandlers(): void {
this.$rootScope.$on("$routeChangeStart",() =>; {
this.onRouteChangeStart.call(this);
});
}
private onRouteChangeStart(): void {
console.log(this.title);
}
}
angular.module("app")
.controller("homeController", HomeController);
}