We’ve moved much of our code over to TypeScript. There are a lot of benefits. To start, you can just dump your javascript files directly into typescript “.ts” files and it will compile them for you and web-essentials plugins will minify them for you everytime you click “save”.
The next step is to take advantage of the programming language and start using it as a real tool. The most effective approach to dealing with AngularJs in TypeScript, for me, has been to simply turn every controller and factory into a class object.
Here is an example of a simple controller that is attached to a pre-existing application “app” and pulls data using a factory called adminfact.
////// interface IRouteParams extends ng.route.IRouteParamsService { userId: number; } class UserCtrl { public valueToUseOnPage:string; static $inject = [ '$http', '$log', '$location', '$window', 'adminFact', '$cookies','$routeParams']; constructor( private $http: ng.IHttpService, private $log: ng.ILogService, private $location: ng.ILocationService, private $window: ng.IWindowService, private adminFact: Application.Services.IMyService, private $cookies: ng.cookies.ICookiesService, private $routeParams: IRouteParams ) { var userId: number = $routeParams.userId; console.log($routeParams.userId); this.valueToUseOnPage = "DAN " + userId; adminFact.GetOffices(function (data: Object, status:number) { }); } } app.controller("UserCtrl", UserCtrl);
right at the top you see:
//////
All that does is let typescrypt know where to get the object types and create some intelliesense for us. Usually you can just drag the file right over and drop it on your typescript page, but sometimes I’ve found I have to type it in manually.
Then we have route parameters. We use ng-route for our SPAs, so we constantly need to get the route parameters. Here’s how you get them in TypeScript.
First, you’re going to create an “interface”. That’s really just kind of a template that helps TypeScript know that you’ve got a RoutParms object and it’s got a few features. Almost like a model in MVC.
interface IRouteParams extends ng.route.IRouteParamsService { userId: number; }
now you need to get that into your controller’s class. It’s pretty simple once you figure it out.
The class has a “constructor”. That’s just where everything from the outside is going to be defined. In our case, we’re bringing in a bunch of stuff. It’s just like how you do in the controller line for normal angular, but it’s “injected”. The first step is to do the $inject, like this:
static $inject = [ '$http', '$log', '$location', '$window', 'adminFact', '$cookies','$routeParams'];
Now, that’s actually optional. However, without it, your minification doesn’t work. It’s exactly like how you used to do this:
app.controller("somename",["$http", "$scope",function($http,$scope){ -some stuff here }]);
instead of
app.controller("somename", function($http,$scope){ -some stuff here });
but they both work if not minified.
Anyway, the next step is to actually build that constructor:
constructor( private $http: ng.IHttpService, private $log: ng.ILogService, private $location: ng.ILocationService, private $window: ng.IWindowService, private adminFact: Application.Services.IMyService, private $cookies: ng.cookies.ICookiesService, private $routeParams: IRouteParams )
there are a lot of these ng.Interfaces. You can download just about anything you want from here https://github.com/DefinitelyTyped/DefinitelyTyped
Just pop those files in any directory and Typescript will find them and just figure it out. (very very nice).
Now, here’s the next step. If you want to get something to your webpage, it has to be declared as a public variable in the class. As you can see, we have
public valueToUseOnPage:string;
then, inside our constructor, we can assign that a value. Here’s the uber simple look.
if we had a controller like this:
class UserCtrl { public valueToUseOnPage:string; constructor( ) { this.valueToUseOnPage = "DAN "; } } app.controller("UserCtrl", UserCtrl);
and our route setup was like this
.when('/users/:userId', { templateUrl: '/admin/partials/user.html', controller: 'UserCtrl as vm' })
then on our HTML view we could have:
Hi, here is some data: {{vm.valueToUseOnPage}}
That’s about as uber simple as it gets.
Let’s now move on to Factories, which is where the rubber hits the road.