0

I'm writing an application using angular and typescript.
I'm using ng-grid and I have to handle the afterSelectionChange event. I tried to set the event handler in two ways

this.$scope.settoriGridOptions.afterSelectionChange = this.afterSelectionChange;  

where this.afterSelectionChange is a method of the controller class,
and

  this.$scope.settoriGridOptions.afterSelectionChange = (... ) => {};  

including the code inside, but in both cases the this pointer is incorrect and I cannot access to the services of the controller.
how can I fix this?

after a more tests and reading a few articles I see that the problem is the implicit passing of the this pointer as parameter in the function call.

if I write

$scope.filtroSoluzione = this.filtroSoluzione;

when called the this pointer is set to null, but if I write

$scope.filtroSoluzione = () => { return this.filtroSoluzione() };

or

$scope.filtroSoluzione = () => { .. inline code ... };

the this pointer I set correctly.
How can I have a more consistent behavior? I don't like to write always the code inside because this makes the class harder to read and navigate

thanks,
Luca

Luca Morelli
  • 2,530
  • 3
  • 28
  • 45
  • 1
    Need to see more of your code, I think. For instance we need to see why you need to use `this` to access `$scope`... – Anthony Chu Oct 22 '14 at 16:44

1 Answers1

1

Thanks for the extra information in your edits, I now see the problem.

class foo {
    public afterSelectionChange = () => {
        console.log(this);
    }  
}

When you declare your function like I did above, your this is the instance instead of what you are seeing know because it captures the this variable. It comes with a cost though, because now it creates a new afterSelectionChange function for every instance of your class. In this case I think it is still what you want though.

var foo = (function () {
    function foo() {
        var _this = this;
        this.afterSelectionChange = function () {
            console.log(_this);
        };
    }
    foo.prototype.baz = function () {
        console.log(this);
    };
    return foo;
})();

In the above code-gen you can see the difference when declaring the function with name = () => {} and the normal way.

Another solutions might be this:

this.$scope.settoriGridOptions.afterSelectionChange = this.afterSelectionChange.bind(this);

But I don't find that really nice either... (this should work with the normal public afterSelectionChange() {} declaration you are used to.

Dick van den Brink
  • 13,690
  • 3
  • 32
  • 43
  • Ok, thanks. coming back to the questions I don't understand if and how I can overcome this problem and use a method as an event handler, to have a more consistent behavior and cleaner code. – Luca Morelli Oct 24 '14 at 16:13
  • When you declare it with "public afterSelectionChange = () => { }" you can user It as a eventhandler with the code you had (this.$scope.settoriGridOptions.afterSelectionChange = this.afterSelectionChange) and can still call it as a normal method if you want with this.afterSelectionChange(). You are right that it isn't consistent with the other method declarations, but there isn't a nice other way (that I know of). I edited my post above wit another solutions. – Dick van den Brink Oct 24 '14 at 16:41
  • thanks, the second solution is much better and I have much more cleaner code – Luca Morelli Oct 25 '14 at 16:04