Search code examples
angularjsangularjs-service

Is this an appropriate use of an AngularJS Service?


I have an app with many views that are varied and numerous enough to justify dynamically loading CSS files, based on which view is active at the time.

I looked into various ways of dynamically 'loading' CSS files with angular, and even found a plugin that worked, though it was kind of clunky in its implementation.

I did some research on a native JS way to do this and decided to implement it in a more 'angular way'. I inject the service below into the routes' controller.

Is my method of implementation (using a service) correct? If not, what is the correct venue for logic of this kind?

HTML:

<head>
...
    <link id="library-css" href="~/Styles/libraryCSS" rel="stylesheet" type="text/css" disabled />
    <link id="results-css" href="~/Styles/resultsCSS" rel="stylesheet" type="text/css" disabled />
...
</head>

The AngularJS Service:

myServices.service("CSSLoader", [function () {

    var cssLinks = {},
        linkToActivate = {};

    (function init() {
        //loading the <link> elements into the cssLinks object for later retrieval
        cssLinks = {
            library: document.getElementById("library-css"),
            results: document.getElementById("results-css")
        };
    })();

    this.loadCSS = function (cssReference, retainPreviouslyLoadedCSS) {
        if (!cssReference) { throw "CSS Link must be provided.";}

        if (!retainPreviouslyLoadedCSS) {
            //first disables any links that are active
            for (var cnt in cssLinks) {
                cssLinks[cnt].disabled = true;
            }
        }

        linkToActivate = cssLinks[cssReference];
        if (!linkToActivate) { throw "CSS Link, (" + cssReference + "), that was provided cannot be found."; }

        linkToActivate.disabled = false;
    };

}]);

Thanks!


Solution

  • please find a plunker I created for you. It is based on a directive that watches a scope variable that corresponds to its own id.

    app.directive('disablecss', function() {
      return {
        link: function(scope, element, attrs) {
          scope.$watch('cssToSet.'+attrs.id, function(value,oldvalue) {
    

    where the attrs.id corresponds to the link id where the directive is set

       <link href="resultCSS.css" id="resultCSS" rel="stylesheet" disablecss />
        <link href="libraryCSS.css" id="libraryCSS" rel="stylesheet" disablecss />
    

    The scope attribute is automaticaly modified by the controller associated to the partial views

    app.config(function($routeProvider) {
      $routeProvider.
        when('/view1', {
            controller:'View1Ctrl', 
            templateUrl:'partial1.html'
        }).
        when('/view2', {
            controller:'View2Ctrl', 
            templateUrl:'partial2.html'
        }).
        otherwise({redirectTo:'/'});
    });
    
    
    app.controller('View1Ctrl',['$scope',function($scope,$rootscope){
      $scope.cssToSet.resultCSS=true;
      $scope.cssToSet.libraryCSS=false;
    }]);
    
    idem for View2Ctrl
    

    Do not hesitate if something is not clear.Bye