Steve Steve - 5 months ago 32
AngularJS Question

Angular 1.4 UI Router: sub-routes?

I have a site where some pages have a header, content, footer while others might have a different setup. Each "section" of the site has its own module.




Update



Here is a plunker of the current state of things: https://plnkr.co/edit/G5CdPPtULVeI1Lfa9Rjg?p=preview

You can see the home state loads, and has 3 views that load a header and footer (from their module folders) and homepage content. I am trying to add a link to load the next set of views into the original ui-view on the index page to shows the "sample" page with its header, content, and footer views.




So I am refactoring my app to have one ui-view at the root that loads a sub-route in each module. I got this to work with the default route, which loads the "home" module into the main view:

angular.module('app').config(function ($stateProvider) {
$stateProvider.state('otherwise', {
url: '*path',
template: '',
controller: function ($state) {
$state.go('home.page');
}
});


});

And the
home.routes.js
file is like so:

angular.module('app').config(function ($stateProvider) {
$stateProvider.state('home', {
url: '/home',
templateUrl: 'modules/home/home.html',
abstract: true,
controller: 'HomeController as home',
data: {
pageTitle: 'Home Page'
}
})
.state('home.page', {
views: {
header: {
templateUrl: 'modules/header/header.html'
},
content: {
templateUrl: 'modules/home/home.content.html'
},
footer: {
templateUrl: 'modules/footer/footer.html'
}
}
});
});


It works as expected. The abstract route loads
home.html
, which is simply my named views:

<div ui-view="header"></div>
<div ui-view="content"></div>
<div ui-view="footer"></div>


But I am having a problem linking to a second module from the home page. I created a module "sample" with the exact same setup as above, literally duplicated and renamed the files and routes to "sample" from "home".

On the home.content.html page, I am trying to create a link to the second module "sample" with
a ui-sref="sample">Sample Section</a>
but it errors out "could not transition to the abstract state 'sample'".

I also tried
a ui-sref="sample.page">Sample Section</a>
which does not throw any console errors but goes nowhere. I thought I had this, but now I am confused.

the routes for sample.routes.js:

angular.module('app').config(function ($stateProvider) {
$stateProvider.state('sample', {
url: '/sample',
templateUrl: 'modules/sample/sample.html',
abstract: true,
controller: 'SampleController as sample',
data: {
pageTitle: 'Sample Page'
}
})
.state('sample.page', {
views: {
header: {
templateUrl: 'modules/header/header.html'
},
content: {
templateUrl: 'modules/sample/sample.content.html'
},
footer: {
templateUrl: 'modules/footer/footer.html'
}
}
});
});

Nix Nix
Answer

Example is below.

Here we go. So create a sep landing page (home). For all the states you want to be in the main part of your app you can use a sep tree called main. If you make your first main state abstract you can technically just have a bunch of child states.

Index page:

<div ui-view=""></div>

Views:

<script type="text/ng-template" id="modules/main/main.content.html">
  main content
</script>

<script type="text/ng-template" id="modules/footer/footer.html">
  footer
</script>
<script type="text/ng-template" id="modules/header/header.html">
  header
</script>
<script type="text/ng-template" id="modules/home/home.content.html">
  content
</script>

<script type="text/ng-template" id="modules/home/home.html">
  Nicks {{test}}
  <a ui-sref="main">Test</a>
</script>

Javascript:

myApp.config(function($stateProvider, $urlRouterProvider) {
  $urlRouterProvider.otherwise('/home');
         $stateProvider.state('home', {
    url: '/home',
    controller: 'HomeController as home',
    templateUrl: 'modules/home/home.html'
    });

  $stateProvider.state('main', {
    url: '/main',
    views: {
      'header@main': {
        templateUrl: 'modules/header/header.html'
      },
      '': {
        templateUrl: 'modules/main/main.html'
      },
      'content@main':{
        templateUrl: 'modules/main/main.content.html'
      },
      'footer@main': {
        templateUrl: 'modules/footer/footer.html'
      }
    }
  });
});

Sample fiddle