How to have states for hierarchial data using ui-router in angular js?

203 views Asked by At

I need to have a url structure in place for hierarchical categories using angularjs ui-router.

Example;

Category tree is like below:

  • Root
  • -Application 1
  • --Category level 1
  • ---Category level 2
  • ----Category level 3
  • -Application 2
  • -Application 3

The url xyz.com/application-1/category-1 will display articles in category level 1, similarly xyz.com/application-1/category-1/category-2/category-3 will display articles in category level 3. This can go upto the 4 or 5 levels of categories.

According to my understanding, i will have to define states for each of the category levels and all those states can access the same template and controller. Is there a better, smarter way of implementing these states?

2

There are 2 answers

3
Ram_T On

Use stateProvider with nested states and views https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

$stateProvider.state('/home', {
     url: '/home',
     templateUrl: '',
     controller: ''
})
.state('home.app1', {
     url: '/home/app1',
     templateUrl: '',
     controller: ''
})
.state('home.app1.cat1', {
     url: '/home/app1/cat1',
     templateUrl: '',
     controller: ''
})
.state('home.app1.cat1.cat2', {
     url: '/home/app1/cat1/cat2',
     templateUrl: '',
     controller: ''
})
.state('home.app1.cat1.cat2.cat3', {
     url: '/home/app1/cat1/cat2/cat3',
     templateUrl: '',
     controller: ''
})
.state('home.app2', {
     url: '/home/app2',
     templateUrl: '',
     controller: ''
})
.state('home.app3', {
     url: '/home/app3',
     templateUrl: '',
     controller: ''
})
$routerUrlProvider.otherwise('/home'); // if no path matched

I didn't mention named views. you can go through the link and It helps a lot.

But the above makes heavy structuring of states. So, you need to display a relevant info in a single state. For example, if there are three categories, and you want to show in single page then you can define a state like this.

.state('home.app1',{
   url: '/home/app1',
   views: {
    "view1": {
      templateUrl: 'cat1.html',
      controller: ''
    },
    "view2": {
      templateUrl: 'cat2.html',
      controller: ''
    },
    "view3": {
      templateUrl: 'cat3.gtml',
      controller: ''
    }
   }
})

Or you can have a single parent controller for all the views.

now, in html you will have

<div>
  <div ui-view="view1"></div>
  <div ui-view="view2"></div>
  <div ui-view="view3"></div>
</div>
1
federico scamuzzi On

What about use angular ui-router and abstract routing?...something like:

app.config([
    "$stateProvider",
    "$urlRouterProvider",
    "$ocLazyLoadProvider",
    "$locationProvider",
    function (
        $stateProvider,
        $urlRouterProvider,
        $ocLazyLoadProvider,
        $locationProvider) {

        $urlRouterProvider.otherwise("/index/main");


        $stateProvider

            .state("application1", {

                abstract: true, // <-- MEAN IT?S  A PARENT URL / TEMPLATE
                url: "/index",
                templateUrl: "/app/view/template/common/application1.html"
            })
            .state("application1.category1", { //<-- MEANS IT'S A CHILD OF index FATHER
                url: "/main",
                templateUrl: "/app/view/template/application1/category1.html",

                controller: "HomeController",
                controllerAs: "homeCtrl"


            })

So the index routing marked as abastract is the 'father' of multiple child