Best practice for using $rootscope in an Angularjs application?

前端 未结 3 1039
情话喂你
情话喂你 2020-12-02 00:51

We have a large Angularjs 1.6 application that has $rootscope scattered throughout the app in over 200 places in filters, services, routes, etc.. so it needs to be refactore

3条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-02 01:06

    From ng-book:

    When Angular starts to run and generate the view, it will create a binding from the root ng-app element to the $rootScope. This $rootScope is the eventual parent of all $scope objects. The $rootScope object is the closest object we have to the global context in an Angular app. It’s a bad idea to attach too much logic to this global context, in the same way that it’s not a good idea to dirty the JavaScript global scope.

    You are right, you should definitely use Services to share data and logic between your modules.

    Putting a lot of logic in your $rootScope means having bad maintainability and modularity in your application, it is also very difficult to test issues.

    I highly suggest you to take a look at:

    • Services AngularJS Documentation
    • Thinkster brilliant article on how to share data between controllers
    • Screencast by Simpulton
    • @Breck421 answer to this question

    I know it may be easy to attach everything to $rootScope, but It is just difficult to work on it, make little changes, reusing your code for other applications or modules and test your application in general.

    EDIT

    Recently I had to fetch some items from API and catch these items in order to show them in a certain view. The item fetching mechanism was in a certain Factory, while the mechanism to format and show the items was in a Controller.

    So, I had to emit an event in the Factory when items got fetched and catch this event in the Controller.

    $rootScope way

    //Factory
    $rootScope.$broadcast('refreshItems', items);
    //Controller
    $scope.$on('refreshItems', doSomething());
    

    It clearly worked but I didn't really like to use $rootScope and I've also noticed that the performance of that task were pretty miserable.

    Then I tried giving a shot to Postal.js:

    Postal.js is an in-memory message bus - very loosely inspired by AMQP - written in JavaScript. Postal.js runs in the browser, or on the server using node.js. It takes the familiar "eventing-style" paradigm (of which most JavaScript developers are familiar) and extends it by providing "broker" and subscriber implementations which are more sophisticated than what you typically find in simple event emitting/aggregation.

    I tried using Postal.js for this kind of needs and I found out that it is really faster than using $rootScope for this purpose.

    //Factory
    $scope.$bus.publish({
                      channel : 'reloadItems',
                      topic   : 'reloadItems'
                      data    : items
    );
    
    //Controller
    $scope.$bus.subscribe({
      channel  : 'reloadItems',
      topic    : 'reloadItems',
      callback : function () {
        resetAndLoadItems();
      }
    });
    

    I hope I've been helpful.

提交回复
热议问题