0

i want to convert existing directive in javascript to typescript. How do i convert below function

    $scope.loadData = function () {
        $scope.tableParams = $cspagination.initPromise(getPagedData);
    };

So I am trying to write it as

  class controller {
    this $scope.loadData = (): void {
      .....
      .....
    };
  }

but it is giving error that this is not available on class level. then i tried

  class controller {
    public $scope.loadData = (): void {
      .....
      .....
    };
  }

but this also does not work. its obvious that I cannot define a new public property on $scope, but then atleast I should be able to assign value to it.

so how do I dynamically add functions on $scope?? The workaround I could think of is creating a function extendScope and then

   class controller {
    public loadData = (): void => {
      .....
      .....
    };

    private extendScope = (): void =>{
       this.$scope.loadData = this.loaddata;
    }

  constructor(){
      this.extendScope();
  }

  }

but then this feels like a hack.. are there any cleaner ways of doing this?

2
  • This is no hack. Normally in javascript you do it on 'constructor'-time, in typescript in the constructor as well, though you should not make the loadData method public, if you only want to assign it to the $scope Commented Aug 10, 2016 at 8:36
  • extendScope is redundant, it is as simple as angular.extend(this.$scope, this) or Object.assign(this.$scope, this) (considering that all this methods are arrows and keep their contexts). It should feel like a hack because it is a hack, the proper way to do this is controllerAs. Commented Aug 10, 2016 at 13:29

2 Answers 2

1

The way I go - is to create custom scope definition (i.e. inteface), e.g.:

export interface IMyScope  extends ng.IScope
{
    loadData: () => void;
    otherFunction: function;
    ...
    Ctrl: MyCtrl;
}

and Controller constructor now requires that interface

export class MyCtrl
{
    static $inject = ["$scope", ...];
    constructor(protected $scope: IMyScope  ,
        ...)
    {
       this.$scope.Ctrl = this; // we can use "controllerAs" as well
        // and here we can add these functions
       this.$scope.loadData = this.loadData;
       this.$scope.otherFunction = function() {};
       ...
    }

    public loadData = (): void => {
       //.....
    }

See more here:

Sign up to request clarification or add additional context in comments.

3 Comments

ok, I used example with not function properties- defined on IMyScope.. now I adjusted that example.. hope it helps a bit. But I would not use the $scope.loadData but $scope.Ctrl.loadData.... so in template ng-click="Ctrl.loadData()"
thats the solution I had thought of, but felt like a hack :(
what is "the native solution" in this case - controllerAs and inside of the template referencing Ctrl.methods()... with combination bindToController you have almost ng2 behavior... anyhow, good luck with Typescript and Angular ;)
1

I don't see anything wrong with this, only that your loadData method shouldn't be public in this case. What I would do though is use the 'controller-as' method:

class controller {
    static ID = "myController";

    // defining methods like this will make them immediately available on 
    // the controller with the 'controller as' method
    public loadData = (): void => {
        //.....
    }

    constructor(){
    }

}

And in your html:

<div ng-controller="myController as $my">
    <button ng-click="$my.loadData()">Load!</button>
</div>

1 Comment

I am aware that controller-as will solve this problem, but then I will have to touch the html pages and that would increase the scope ,I dont want to touch html as of now...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.