Question

I would like to have few global variables that are UI related (i.e. open menu state). I decided to put these in $rootScope so they're always accessible.

This is the code I've written:

(function (angular) {

    angular
        .module("App", [])
        .run(["$rootScope", function ($rootScope) {
            angular.extend($rootScope, {
                ui: {
                    menu: false,
                    ...
                }
            });
        }]);

})(angular);

I've deliberately used angular.extend, to make sure that consecutive manipulations to the same object are retained. And I think it's also more clean and safe than adding several properties to any object one by one.

Problem

Upper code doesn't do anything though. When I run my application and check root scope by calling:

$("body").scope().$root.ui

I get undefined until some property within ui gets manipulated by ng-click directives on my application. Only then my ui gets a reference... But it's still not the one I've defined in the run() function but rather angular generated object property that ng-click directive generated as per expression.

What am I doing wrong?

Était-ce utile?

La solution

Resolved - module got overwritten

Ia managed to resolve it myself. Code contained in the upper question isn't sufficient to show the actual problem in my application. The problem was the way I was loading module requirements and file ordering.

I'm loading files in this order:

app.js
routing.js
service.something.js
...
filter.something.js
...

So I thought to add module requirements to my app module in subsequent files (make ti actually modularized). This would make it simple to either include or exclude particular files without any runtime errors. It would also allow loading additional files dynamically as application runs.

The problem with my code was that I've overridden my original module in subsequent files. When I added all module requirements into app.js everything everything started working.

Possible workaround

I can see that I'm not the only person that would like this kind of functionality. Lasy module requirements loading is possible as per this Google groups' post.

What it does is it creates a new injector function

instanceInjector.loadNewModules = function (mods) {
    forEach(loadModules(mods), function(fn) { instanceInjector.invoke(fn || noop); });
};

that can later be used by individual modules to add themselves as requirement to the main application module by doing this:

$injector.loadNewModules(["Module1", "Module2", ...]);

Although it would be much better (my opinion) if there was an additional function on Module type called requires() so one could do this instead:

angular.module("MainModule").requires(["AdditionalModule", "OtherModule", ...]);

I think that would make it more concise and easy to use and understand.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top