Jimi
Jimi

Reputation: 1907

ui-router dynamic template path

I'm using ui-router 0.2.8. I'm wanting to load a template based on device width. I can get the device width without issue, set it in the scope etc but I can figure out how to bind it to $stateParams. I have the scope variable in another controller which can be accessed the state's controller it's just not available to the state itself. I've tried the templateProvider but that is only returning me a string. What else can I try in order for this to work?

.state('list', {
abstract: true,
url: "/list",
templateUrl: 'views/'+$stateParams.somevalue+'/page.html',
    controller: "myCtrl"
 })
  .state('list.first', {
url: "/first",
templateUrl: "views/first.html"
  })

Upvotes: 18

Views: 17212

Answers (3)

lastlink
lastlink

Reputation: 1755

This reference here was great for me figuring out how to do dynamic templates in angular, but I'd like to update with my own solution.

  • Solution 1 based on Dipesh Kc's (this works great for redefining parent templateUrl for abstract states) Notice I used toParams instead of $stateParams:

    // custom parent template
    .state('template', {
        abstract: true,
        url: "/tm/:tmfolder/:tmview",
        templateUrl: function (toParams) {
            return 'views/' + toParams.tmfolder + '/' + toParams.tmview + '.html';
        },
    })
    .state('template.contacts', {
        url: "/contacts/:folder/:view",
        templateUrl: function (toParams) {
            return 'views/' + toParams.older + '/' + toParams.view + '.html';
        },
    })
    
  • Solution 2 based on biofractal's (there is no way to update a parent templateUrl using this method):

    .state('contact', {
        url: "/contact/:folder/:view"
    })
    
    $rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
        var customStates = ["contact"]
        for (var i = 0; i < customStates.length; i++) {
            if (toState.name.indexOf(customStates[i]) != -1) {
                toState.templateUrl = 'views/' + toParams.folder + '/' + toParams.view + '.html';
                break;
            }
        }
    });
    

Upvotes: 0

Dipesh KC
Dipesh KC

Reputation: 3317

You might be looking for dynamic template name based on the state params

 $stateProvider.state('contacts', {
   templateUrl: function ($stateParams){
     return '/partials/contacts.' + $stateParams.filterBy + '.html';
   }
 })

See the docs for more information https://github.com/angular-ui/ui-router/wiki#templates

Upvotes: 90

biofractal
biofractal

Reputation: 19153

You can access to state params in the $stateChangeStart event. You can also dynamically update the templateUrl there as well.

So perhaps your code might look something like this:

angular.module('app', ['ui.router'])
.run(function($rootScope){
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams) {
        if (toState.name === 'list') {
          toState.templateUrl = 'views/'+toParams.somevalue+'/page.html';
        }
    });
}

You might also want to take a look at the onEnter callback supported by ui.router. I have not used this before but it might be neater than putting your template generating code into the $stateChangeStart event.

Upvotes: 12

Related Questions