Question

In the code below I want to know why Cancel is not working if I add it to 'this'. Notice the save() function is added to $scope instead.

<div ng-controller="MyController">
    <button ng-click="save()">Save</button>
    <button ng-click="cancel()">Cancel</button>
</div>
...
app.controller('MyController', function ($scope) {
    $scope.save = function() {
        ...
    };
    this.cancel = function() {
        ...
    };
}
2 Answers

A controller function is a JavaScript constructor function. When a view loads, the associated constructor function is executed and 'this' reference is set to the controller object. Therefore in the MyController constructor function, the cancel() function is created on the controller object, not on $scope.

The HTML view only has access to functions defined on $scope, it cannot see the cancel() function, that is to say that this won't work in the HTML:

<button ng-click="cancel()">Cancel</button>

Let's dig a little deeper:

app.controller('MyController', function ($scope) {
    $scope.buttonClickCounter = 0;
    $scope.handleButtonClick = function() {
        alert(this.buttonClickCounter);
        $scope.buttonClickCounter++;
    };
}

The this inside a function defined on $scope refers to the $scope. When the handleButtonClick() function defined on the $scope object is called, it prints the value of the buttonClickCounter property defined on the $scope.

It is recommended that you avoid using this inside a function defined on $scope. This is because ng-include, ng-switch, ng-repeat, and directives can all create their own child scopes and it becomes confusing which $scope is being affected.