Search code examples
angularjsangularjs-scopecontrollers

Changing attributes of enclosing containers based on current view


This is rather a conceptual than a strictly technical question.

I have the following index.html:

<div class="container"><div ng-view=""></div></div>

In my app.js, I have the following route configuration:

$routeProvider
            .when('/questions', {
                templateUrl: 'views/questions.html',
                controller: 'QuestionsCtrl'
            })
            .when('/result', {
                templateUrl: 'views/result.html',
                controller: 'ResultCtrl'
            })
            .otherwise({
                redirectTo: '/questions'
            });

Which means that, based on the URL, different views are loaded in <div ng-view="">. Now, in order to have those views correctly rendered, I need to set style attributes on the enclosing <div class="container"> (I use Leaflet.js in one of those views and thus I need to temporarily set the width and height of the container to 100%, for a full screen map).

How would I do this best, i.e. "The Angular Way"? I looked at the $viewContentLoaded event of the ngView directive, but it doesn't seem to be the right thing as it seems to be only fired when the respective view is completely loaded and not at the initialization of the view (and thus the map, which needs a correctly styled container from beginning on). Should I use a controller that is defined on the body tag, for example? Or a service? I am completely clueless and want to make it right.


Solution

  • Use a controller that listens to $routeChangeSuccess on the $rootScope.

    <body ng-app="X" ng-controller="app">
        <div class="container" ng-class="containerClass">
            <div ng-view=""></div>
        </div>
    </body>
    

    angular.module('X').controller('app', function($rootScope, $route) {
      $rootScope.$on('$routeChangeSuccess', function(){
        $rootScope.containerClass = angular.lowercase(($route.current.controller || '').replace(/Ctrl$/, ''));
      });
    });