2

I have lately switched to using "this" in the controllers and controllerAs in ngRoute and Directives, rather than $scope directly. Although I really enjoy the way the code looks, I have to bind "this" to each function - manually.

Example:

app.controller('mainController', function ($scope, Restangular) {
    this.title = '';

    $scope.$on('changeTitle', function (event, data) {
        this.title = data;
    }.bind(this)); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

});

I understand why I have to do that ("this" context constantly changes), is there any better solution (cleaner, usable) I should consider doing?

Thanks.

3 Answers 3

8

Fat arrow functions in ES6 are specifically added to solve this problem. With a fat arrow function you inherit the context of the parent scope, so you no longer have to use bind or var that = this. So you could look into transpiring.

app.controller('mainController', function ($scope, Restangular) {
  this.title = '';

  $scope.$on('changeTitle', (event, data) => {
    this.title = data;
  });
});

Angular 2 is written in ES6 and uses the Traceur compiler: http://angularjs.blogspot.sg/2014/03/angular-20.html and here's a short post on how you can use it with your own code: http://www.benlesh.com/2014/03/traceur-is-awesome-but-still-little.html

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

2 Comments

I am getting "Uncaught SyntaxError: Unexpected token =>". It seems like a good solution (I'm using Angular 1.4)
@user3043893 Only the latest Firefox has native support for arrow functions so far, so you need to convert from ES6 to ES5 to run it in most browsers, which the second link tells you how. There are also ways to automate that with grunt/gulp/broccoli or whatever angular people normally use to make it easier on yourself. If it seems overly complicated I would just stick with what you're already doing until you feel more familiar.
3

The simplest way is to put your this inside an object.

app.controller('mainController', function ($scope, Restangular) {
  var self = this;
  self.title = ''; 

  $scope.$on('changeTitle', function (event, data) {
    self.title = data;     // Due to scope inheritance in javascript, self is defined here.   
  });

});

This version is also best practice for many of angular users, including John Papa (he calls it vm instead of self).

https://github.com/johnpapa/angular-styleguide#style-y032

Comments

0

And you can use the

Angular.bind(this, function(){})

as described here and in this answer

so you will have something like:

this.defaultCity = 'myvalue';
callHttpService(this.defaultCity).then(angular.bind(this, function(res) {
    this.defaultCity = res.data;
}));

Comments

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.