Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it better to create objects containing functionality or have loose functions in AngularJS controllers?

Say we have three buttons on our site:

<button>Like</button>
<button>Dislike</button>
<button>Flag</button>

Each button will call their respective functions:

<button ng-click="like()">Like</button>
<button ng-click="dislike()">Dislike</button>
<button ng-click="flag()">Flag</button>

And in the controller it could look something like this:

$scope.like = function() {
  return likes + 1;
}

$scope.dislike = function() {
  return dislikes + 1;
}

$scope.flag = function() {
  return flags + 1;
}

Since cluttering the $scope with too many watchers is bad for performance, wouldn't it be better to do this:

$scope.actions = {
  like: function() {
    return likes + 1;
  },
  dislike: function() {
    return dislikes + 1;
  },
  flag: function() {
    return flags + 1;
  }
}

And then using it like:

<button ng-click="actions.like()">Like</button>
<button ng-click="actions.dislike()">Dislike</button>
<button ng-click="actions.flag()">Flag</button>

Which will reduce the number of watchers from 3 to 1, also giving the benefit of creating grouped functionality. Leading to better readability as well.

From my point of view this makes more sense than having loose functions in your controller, especially since not all controllers can be made lightweight.

The thing that would make me doubt this approach is that I've never come across any examples whatsoever using this method. Is there a reason for this?

Which approach would be better to use in terms of commonly used design patterns, best practice and performance?

EDIT: There has been suggestions that I should instead use controller as syntax, I'm aware of this but this doesn't directly answer my question. As I would like to know which of the two methods that I've mentioned above is the better option, not using the controller as syntax.

like image 351
Chrillewoodz Avatar asked Sep 10 '15 09:09

Chrillewoodz


2 Answers

I have just tried out both your approaches and could not see any difference in performance. This is for two main practical reasons:

  1. It is difficult to test performance of Angular applications, see How to performance test an AngularJS Web Application?.

  2. It would make sense to test for performance only on a bigger scale application and not on such small examples.

I understand however that your question is about a proof of concept. So, in theory, your second method is the better one because it pollutes the $scope less than the other and that's what's recommended.

In future, I would try the controllerAs syntax. Alternatively this is also interesting if you're not a fan of that syntax. Hope this helps.

like image 142
U r s u s Avatar answered Nov 14 '22 00:11

U r s u s


I agree with Jesús Quintana - the numbers of watchers not change.

Also, I advise you to use 'controller as' syntax. It's more conveniently to working for a few $scope's in your page.

For example, in your markup:

<div ng-controller='PageController as page'>
    <button ng-click="page.like()">Like</button>
    <button ng-click="page.dislike()">Dislike</button>
    <button ng-click="page.flag()">Flag</button>
</div>

And in code:

myApp.controller('PageController', function() {
    var page = this;

    page.like = function() {
       return page.likes + 1;
    }

    page.dislike = function() {
       return page.dislikes + 1;
    }

    page.flag = function() {
       return page.flags + 1;
    }
});
like image 2
Salasar Avatar answered Nov 13 '22 22:11

Salasar