0

I would like to persuade my co-worker that it is a better approach to use component directives than to use $rootScope everywhere. I need arguments against his ones because he is very stubborn and a very good speaker (which I am not). He thinks that $rootScope prevents spaghetti code. This week I have refactored the project and there are no more spaghetti but I don't want him to rework everything to $rootScope.

Please tell me about problems and issues that can arise when using $rootScope. Thank you.

EDIT

Are there any security issues with $rootScope?

EDIT 2

My friend came with this construct and wants to put it in every component:

function Controller(service, $rootScope, $scope) {
    var vm = this;

    $scope.a = $rootScope.a;
    $scope.b = $rootScope.b;
    $scope.c = $rootScope.c;

    $rootScope.$watch('mapLoaded', function () {
        $scope.a = $rootScope.a;
        $scope.b = $rootScope.b;
        $scope.c = $rootScope.c;
    }, true);

Would the issue of destroying scopes and removing wathces that @charlietfl described in comments appear? I am definitelly not gonna let him code like this but I need the arguments against it. Thanks again.

Amio.io
  • 20,677
  • 15
  • 82
  • 117
  • Maybe [this](http://stackoverflow.com/questions/16739084/angularjs-using-rootscope-as-a-data-store) will be useful? – LJ.Wizard Feb 25 '16 at 18:47
  • 2
    The biggest issue is that all scopes are derived from `$rootScope`. That means anything that is in $rootScope will be copied many levels down into all child scopes. This can cause collisions, wasted memory, performance problems and similar problems as if you used global variables for everything in a page – charlietfl Feb 25 '16 at 19:04
  • 1
    No spaghetti if you use services efficiently – charlietfl Feb 25 '16 at 19:06
  • 1
    I think you should forget at all about $rootScope, and make the application as much modular: with services, directives and the glue as controllers. Modular code is easier to understand (each module has it's own small meaning), maintain, fix and especially test. With excessive $rootScope usage in the end you'll have a big piece of cake and it will be hard to add new functionality or at least understand what's going on. – Dmitri Pavlutin Feb 25 '16 at 19:22
  • @DmitriPavlutin Currently we have components everywhere. https://docs.angularjs.org/guide/component – Amio.io Feb 25 '16 at 19:27
  • @charlietfl Wasted memory is a thing I didn't know. It will come handy. Thanks. – Amio.io Feb 25 '16 at 19:28
  • 1
    @zatziky One more important point is scopes get destroyed when not being used. – charlietfl Feb 25 '16 at 19:30
  • @charlietfl Does it hold true even for the dreaded $rootScope? – Amio.io Feb 25 '16 at 19:34
  • No ... it lives the full life cycle of the page. So once you put something in rootscope it will be there until page is closed or refreshed. A big app would implode with so many un-testable bugs and problems if it only used rootScope – charlietfl Feb 25 '16 at 19:36
  • And not only do the scopes get destroyed but so do the watchers that are placed in scopes under the hood. There is more to scopes that angular uses internally than just the data or methods that we write. Leaving lots of watchers in rootScope would be pointless, expensive etc – charlietfl Feb 25 '16 at 19:43
  • 1
    @charlietfl The comment on $rootScope memory wasting is misleading. Children scopes are prototypically inherited, not copied. Among the arguments against $rootScope the performance would be the last one. – Estus Flask Feb 25 '16 at 20:12
  • @estus sure they are but constantly storing references on rootscope for arrays and objects and methods that are no longer used means they can't be garbage collected...so long as a reference still exists to those objects – charlietfl Feb 25 '16 at 20:17

2 Answers2

0

$rootScope exists, but it can be used for evil

Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.

Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show just like values on your local $scope.

Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.

Conversely, don't create a service whose only purpose in life is to store and return bits of data.

-- AngularJS FAQ

georgeawg
  • 48,608
  • 13
  • 72
  • 95
0

I will response myself to Edit 2 citing this:

Using $watch means whenever you read this code in the future you’ll have to consider whether it’s being triggered by something else, too.

Amio.io
  • 20,677
  • 15
  • 82
  • 117