0

Using a Typescript class looking something like this:

class MainCtrl {

    constructor() {
        var vm = this;
        vm.variable = "Text";
    }
}

app.controller("MainCtrl", MainCtrl);

Compiles to

var MainCtrl = (function () {
    function MainCtrl() {
        var vm = this;
        vm.variable = "Text";
    }
    return MainCtrl;
})();
app.controller("MainCtrl", MainCtrl);

And since I have not quite grasped IIFE's yet, I cant read from this if the MainCtrlobject is a function I can shove into the controller definition like this or not. And how would I handle injections?

3 Answers 3

1

You need to export you MainCtrl class so your class definition should look like

export class MainCtrl {
   ...
}

If you're referring to how you can $inject in your typescript code then you can use this syntax in your MainCtrl class:

public static $inject = [
        '$scope',
        '$location',
        'MyCustmSvc'
];

And in you TS constructor:

constructor(
        private $scope: IAppNameScope,
        private $location: ng.ILocationService,
        private IMyCustomSvc) {

   var vm = this;
   vm.variable = "Text";
}

Any parameter with an I before it requires you to define a typescript interface for it.

Your compiled JS should now look something like this:

var MainCtrl = (function () {
    function MainCtrl($scope, $location, MyCustomSvc) {
        var vm = this;
        vm.variable = "Text";
    }
    return MainCtrl;

 MainCtrl.$inject = [
       '$scope',
       '$location',
       'MyCustomSvc'
 ];
return MainCtrl;
})();
app.controller("MainCtrl", MainCtrl);
Sign up to request clarification or add additional context in comments.

Comments

0

You can run an initialize step that converts the TS class into a thing you can use. We do something similar for React components- React uses React.createClass to create factories rather than using the classes directly, so we iterate over all of our classes that derive from a specific TS base, and then replace those values with the result of React.createClass.

TS classes are ultimately just variables that you can wrap as you please into another form. Also, if you reflect on some "modules", you can remove that hideous call to App.controller and do that as an init step.

Comments

0

Yes you can use TypeScript classes with Angular.

With TypeScript you do not need to use var vm = this inside your controller. Just use controllerAs 'vm' instead.

Your example above becomes:

export class MainCtrl {

    variable = "text";

}
app.controller("MainCtrl", MainCtrl);

So now you can access this in your views like:

{{vm.variable}}

To inject into your controller you will use the standard Angular $inject annotation. This works nicely with TypeScript.

export class MainCtrl {

    static $inject = ['$http'];
    constructor(private $http) {}

    submit(form: YourForm) {
        this.$http.post('/api/form', form);
    }
}

Now from the view you can submit a form with vm.submit(). $http is injected and accessable from any internal method in the controller.

Notice I use export. This allows you to use the Class type definition within your unit tests.

Not only should Controllers be created as classes. Services should as well. The only difference is Angular will instantiate services as singletons, so there will only be one instance -- where Controllers can be instantiated with many instances.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.