javascriptangularjsangularjs-ng-switch

Angularjs custom component vs ngSwitch directive compilation order


There is a following code snippet:

<my-header></my-header>
<div ng-switch="$ctrl.page">
        <div ng-switch-when="1"><component1></component1></div>
        <div ng-switch-when="2"><component2></component2></div>
        <div ng-switch-when="3"><component3></component3></div>
</div>

I want that component myHeader would be constructed before ngSwitch directive takes an action. Now component1 is constructed before myHeader.

Routing represents following code:

$stateProvider
  .state({
    name: 'myApp',
    url: '/',
    component: 'loader',
  })
  .state({
    name: 'myApp.pages',
    url: 'pages/{id:int}',
    component: 'loader'
  });
$urlRouterProvider.otherwise('/pages/1');

Solution

  • You can achieve this by exposing your controller in the link function inside the myHeader directive.

    With that, you can easily add variables to the controller and control the visibility of the ng-switch div with ng-if. Check the code snippet down here.

    Ah, don't forget to add ng-cloak to the div containing the ng-switch directive.

    angular
            .module('app', [])
            .controller('TestController', function($scope) {
                this.page = 1;
            })
            .directive('myHeader', function () {
                return {
                    link: function (scope, element, attrs) {
                        // With element.controller() we can reach the controller that is wrapping our directive. Then, we can simply set the headerIsLoaded variable to true.
                        element.controller().headerIsLoaded = true;
                    },
                    scope: true,
                    templateUrl: 'my-header.html'
                }
            });
    
    <div ng-controller="TestController as ctrl">
    
        <my-header></my-header>
    
        <!-- Add a visual feedback so user knows the components are being loaded -->
        <div ng-if="!ctrl.headerIsLoaded">
            Loading...
        </div>
    
        <!-- If ctrl.headerIsLoaded is set to true, the ng-switch will appear -->
        <div ng-if="ctrl.headerIsLoaded"
             ng-cloak>
            <div ng-switch="ctrl.page">
                <div ng-switch-when="1">
                    Page 1
                </div>
                <div ng-switch-when="2">
                    Page 2
                </div>
                <div ng-switch-when="3">
                    Page 3
                </div>
            </div>
        </div>
    
    </div>