1

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"
              }
            ]
        }
      ]

  }
]

1 Answer 1

1

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:

Sign up to request clarification or add additional context in comments.

1 Comment

This is an amazing answer! I think my understanding of Angular just shifted to a whole new level.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.