1

I'm trying to change a parent view template on runtime - inside a service.

My app config looks like:

$stateProvider
.state('base', {
    abstract: true,
    views: {
        'header':       {
            controller: 'HeaderCtrl',
            templateUrl: 'header.html'
        },
        '': {
            template: '<div ui-view="main"></div>'
        }
    }
})
.state('base.home', {
    url: '/',
    views: {
        'main': {
            controller: 'SomeContentCtrl',
            templateUrl: 'content.html'
        }
    }
});

I then have a service which is called from SomeContentCtrl that will listen for an event and upon such event I want to set the templateUrl for the header to null. Something like:

angular
    .module('RemoveTemplate', [ ])
    .factory('RemoveTemplate', ['$window', '$view', '$state',
        function RemoveTemplate ( $window, $view, $state ) {

            var windowElem  = angular.element($window);

            var listen   = function ( ) {
                windowElem.on('RemoveTemplate', function ( event ) {
                    $view.load('header@base', {
                        templateUrl: null
                    });

                    // Trying both, even tried without refreshing the state
                    $state.reload();
                    $state.go('wh.lobby');
                });
            };

            return {
                listen:  listen
            };

        }
    ]);
});

But this isn't working at all. Have anyone came across a similar use case before?

Thanks

jribeiro
  • 3,387
  • 8
  • 43
  • 70

2 Answers2

3

You can specify a templateURL function that runs each time you navigate to the state.

https://github.com/angular-ui/ui-router/wiki/Quick-Reference#template-templateurl-templateprovider

this method can check if it should supply a url or something else; example:

$stateProvider.state('home', {
        url: '/',
        templateUrl: function () {
            if (header === true) {
                return 'app/templates/home.html';
            } else {
                return somethingElse;
            }
        }
    })
Rodik
  • 4,054
  • 26
  • 49
  • Thanks for the answer. I don't think this meets the requirements provided above since it doesn't allow the change of the template after it's loaded. Am I correct? – jribeiro Jul 02 '14 at 12:20
  • This will work on every navigation. if you want to remove a template while in regular runtime, you can just empty the DOM element at any time. – Rodik Jul 02 '14 at 12:21
0

If you want to 'hide' the header section without removing the html try to use a ng-show directive inside the header tag and check the actual state.

<div ng-show="state.is('base')">

This way you only need to inject the $state service in the controller. When the state is base the div will show, if you navigate to child states it will hide.

p.s. $state.is returns a boolean, this method works with ng-if as well.

LookForAngular
  • 1,030
  • 8
  • 18
  • 1
    This is not the goal and could be achieved on the state config which would be a cleaner approach from my perspective. – jribeiro Jul 02 '14 at 13:10
  • I'm intrested. How do you achieve it from the state config? – LookForAngular Jul 02 '14 at 13:36
  • you can reference parent views through 'nameOfView@nameOfState' and then set the template to whatever you want. But this is unrelated to my problem. I want to remove a view dynamically in a clean angular fashion. https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views#view-names---relative-vs-absolute-names You could also use the onEnter, onExit callbacks. Anyways this doesn't answer my question. Thanks – jribeiro Jul 02 '14 at 15:06