Best practice for using $rootscope in an Angularjs application?

前端 未结 3 1052
情话喂你
情话喂你 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:09

    From Angluar docs: Every application has a single root scope. All other scopes are descendant scopes of the root scope. Scopes provide separation between the model and the view, via a mechanism for watching the model for changes.

    Of course this is going to come down to a matter of opinion and style. I tend to follow a style very close to John Papa's Angular Style Guide.

    In keeping with the two, and following a good separation of concerns strategy my architecture contains factory models that are shared across the application. My controllers in turn are all bound to the services that hold the shared data.

    Using $rootScope as the global event bus is exactly how Angular uses it. Should you tag along and do the same? I don't see why not. But if you are, make sure that the purpose is clearly defined and maybe even use your own service to register events to the global event bus. That way you are decoupling your app from Angular, and if you ever decide that you want to change the framework in which your global event bus lives then you can change it in one place.

    This is what I'm suggesting:

    Global event bus

    // Angular specific: add service to module
    angular.module('app').factory('globalEventBus', GlobalEventBus);
    
    // Angular specific: inject dependencies
    GlobalEventBus.$inject(['$rootScope']);
    
    // Non framework specific. 
    // param: fameworkEventBus will be $rootScope once injected 
    function GlobalEventBus(fameworkEventBus) {
    
      var globalEventBus = this;
    
      globalEventBus.registerEvent(params...){
        fameworkEventBus.
      }
    
      return globalEventBus;
    }
    

    Global data models

    My data models are smart and tend to contain functions that provide information about themselves or retrieve/return specific data.

    // Angular specific: add service to module
    angular.module('app').factory('dataModel', DataModel);
    
    function DataModel() {
    
      var dataModel= this;
    
      dataModel.myData = {};
    
      dataModel.GetSpecificData = funtion(param){
        return ...
      }
    
      return dataModel;
    }
    

    The controller

    // Angular specific
    angular.module('app').controller('MyController', MyController);
    
    // Angular specific: inject dependencies to controller
    MyController.$inject = ['dataModel'];
    
    // By convention I use the same parameter name as the service.
    // It helps me see quickly if my order of injection is correct
    function MyController(dataModel) {
    
      var myController = this;
    
      // Bind to the service itself, and NOT to the service data property
      myController.myData = dataModel;
    
      myController.doStuff = function(){
      }
    }
    

    Here is a fun post about binding to services and not to service properties.

    All in all you have to be the judge of what works best for you. A good system architecture and good style have saved me countless hours of solving completely avoidable problems.

提交回复
热议问题