How to share data between controllers in angular app in the right way

前端 未结 3 552
悲哀的现实
悲哀的现实 2021-01-14 10:26

Well, seems that this is not the first question about this subject, but...

I know that we can use service or events for this, but there are many posts on the interne

3条回答
  •  一生所求
    2021-01-14 10:37

    You can bind the context of the controller directly to the service. This gives you several benefits: (1) you don't have to use $scope a lot; (2) you don't have to define properties in your directive's isolate scopes; (3) you don't have to touch $rootScope; (4) you don't have to use $watch or $observe, since everything that needs to be bound to something will be bound to the internal API of your global service.

    This pattern is useful for applications that need to share and be aware of lots of data between a large number of components. I used this pattern in a video player where many distantly-related parts of the application had to share information and have access to each other's state: for instance, how many video players were in the view, the current time, duration and source of each player, etc.

    This pattern isn't particularly suited for building truly reusable components. If you choose to use a service like this, the directive is hardcoded to rely on a certain service. However, you can define all the properties your application's components need in a single value component which is handy for defining your internal API.

    With dirty checking, I'm not sure if sharing a potentially large object is a performance burden.

    directive

    function() {
        return {
            //if you want the service to hold all the data the directive needs
            //you don't need to define any properties here
            scope: {},
            controller: "SomeCtrl"
        };
    }
    

    directive's controller

    angular
        .module("app")
        .controller("SomeCtrl", ["globalService", function(globalService) {
            var vm = this;
            vm.globalService = globalService;
        }]);
    

    html

    {{vm.globalService.someProperty}}

    in some deeply nested template url

    
    
    
    {{panel.display}}

    constants

    angular
        .module("app")
        .value("internalAPI", {
            someInitializedThing: true,
            someConfig: [
                { state: true, display: "foobar" },
                { state: false, display: "starts off false" }
            ],
            dashboard: {
                sidebar: {
                    panelConfig: [
                        { display: "one panel", state: true },
                        { display: "special panel", state: false }
                    ]
                }
            }  
        });
    

    let your service register the API you've defined

    angular
        .module("app")
        .service("globalService", ["internalAPI", function(API) {
            var tmp = {};
            for (var p in API)
                tmp[p] = API[p];
            return tmp;
        }])
    
        //now someplace else, globalService.someNavBar = true
    

提交回复
热议问题