Saeed Abbaspour
Saeed Abbaspour

Reputation: 329

nested states using Angular ui-router

I am learning Angular and trying to design a website that has nested states. First of all I am not sure if my solution is right! the data structure is like the sample below. I am trying to display everything in one page which I call it "showcase". On showcase (state:"showcase"), you will see a list of all the categories and if you click on for example category1 all the subcategories in category1 will be displayed in the same page but different state (state:showcase.category1). This goes the same for each subcategories as well so if you click on e.g. subcategory2 it's supposed to display all the products in the subcategory2 and change the state to showcase/category1/subcategory2. I am trying to build this all static as well so there will be no server side.

I have created a little Plunker you can check out here -- > http://plnkr.co/edit/AkuCJXev6NzmgbqBMUrn

Is this a good solution for what I'm trying to accomplish, and if not how should I redirect my approach.

If this is the right approach how can I manipulate DOM in different states dynamically (e.g. ui-sref for links)

Thanks!

[ 
  {
    "title" : "category1",
    "url" : "category1",
    "imgUrl" : "http://lorempixel.com/200/200",
    "subCats" : [
        {
          "title" : "subCat1",
          "url" : "subCat1",
          "imgUrl" : "http://lorempixel.com/200/200",
          "products" : [
              {
                "title" : "product1",
                "imgUrl" : "http://lorempixel.com/200/200"
              },
              {
                "title" : "product2",
                "imgUrl" : "http://lorempixel.com/200/200"
              }
            ]
        },
        {
          "title" : "subCat2",
          "url" : "subCat2",
          "imgUrl" : "http://lorempixel.com/200/200",
          "products" : [
              {
                "title" : "product3",
                "imgUrl" : "http://lorempixel.com/200/200"
              },
              {
                "title" : "product4",
                "imgUrl" : "http://lorempixel.com/200/200"
              }
            ]
        }
      ]
  },
  {
    "title" : "category2",
    "url" : "category2",
    "imgUrl" : "http://lorempixel.com/200/200",
    "subCats" : [
        {
          "title" : "subCat3",
          "url" : "subCat3",
          "imgUrl" : "http://lorempixel.com/200/200",
          "products" : [
              {
                "title" : "product5",
                "imgUrl" : "http://lorempixel.com/200/200"
              },
              {
                "title" : "product6",
                "imgUrl" : "http://lorempixel.com/200/200"
              }
            ]
        },
        {
          "title" : "subCat4",
          "url" : "subCat4",
          "imgUrl" : "http://lorempixel.com/200/200",
          "products" : [
              {
                "title" : "product7",
                "imgUrl" : "http://lorempixel.com/200/200"
              },
              {
                "title" : "product8",
                "imgUrl" : "http://lorempixel.com/200/200"
              }
            ]
        }
      ]

  }
]

Upvotes: 1

Views: 193

Answers (1)

Radim Köhler
Radim Köhler

Reputation: 123861

What your definition is missing is the view nesting - and that means $scope inheritance. I updated your plunker and make it working.

I changed your templaes, to also provide target for your child state (see the <ul> is now wrapped with ui-view - target for child)

<h1>Showcase</h1>
<div ui-view="">
  <ul>
    <li class="text-center thumbnail list-inline" ng-repeat=" category in categories">
      <img src="{{category.imgUrl}}" alt="" />
      <a ui-sref="showcase.category({category: category.url})">{{category.title}}</a>
    </li>
  </ul>
</div>

That will replace this content with a child content. And also we will have the $scope inherited (read more here about sharing data among states)

Here is updated state def:

.state('showcase', {
  url: "/",
  templateUrl: "pages/showcase.html"
})
.state('showcase.category', {
  url: "^/:category",
  templateUrl: "pages/subcategory.html",
  controller: 'categoryCtrl',
})
.state('showcase.category.subcategory', {
  url: "/:subcategory",
  templateUrl: "pages/product.html",
  controller: 'productCtrl',
});

And new controllers:

.controller('categoryCtrl', ['$scope', '$stateParams',
    function($scope, $stateParams) {
      $scope.category = $stateParams.category;
      $scope.subCats = _.find($scope.categories, { "url": $stateParams.category }).subCats;
    }
  ])
.controller('productCtrl', ['$scope', '$stateParams',
    function($scope, $stateParams) {
      $scope.subcategory = $stateParams.subcategory;
      $scope.products = _.find($scope.subCats, { "url": $stateParams.subcategory}).products;
    }
  ])

Check the updated plunker here

Also check these:

Upvotes: 1

Related Questions