0

So I'm creating a product site.. kind of like a webshop.

The site will have a header with top menu, a sidebar with filters, a content area and a footer. I want the sidebar filters to update dependent on what top menu has been selected.

So the filters on the left side should update when I select a new item in the top menu and products will be filtered when checking/unchecking the filters.

What would a good structure for this app?

  • Should I have a "main view" that loads header, sidebar, main content and footer?
  • Or perhaps I should separate them into one view each in the index.html?
  • Or should I divide them into 3 views? Header, content, footer?

Main problem I see is that the products that should be shown are dependent on the sidebar filter, then the sidebar filter is dependent on the selected top menu..

Ideas are most welcome :)

App wireframe

Mackelito
  • 4,213
  • 5
  • 39
  • 78

1 Answers1

1

I wanted to share with you my approach. There is a working plunker.

Let's have three areas layout - top, left, main. And these could be states:

$stateProvider 
    .state('index', {
        url: '/',
        views: {
          '@' : {
            templateUrl: 'layout.html',
            controller: 'IndexCtrl'
          },
          'top@index' : { templateUrl: 'top.html',},
          'left@index' : { templateUrl: 'left.html',},
          'main@index' : { templateUrl: 'main.html',},
        },
      })
    .state('index.list', {
        url: '^/:category',
        templateUrl: 'list.html',
        controller: 'ListCtrl'
      })
    .state('index.list.detail', {
        url: '/:id',
        views: {
          'detail@index' : {
            templateUrl: 'detail.html',
            controller: 'DetailCtrl'
          },
        },
      })

The index will create a scope which will be inherited into each child and grand child state. So we can use $scope.Model to keep the data consolidated all the way down.

These would be controllers:

.controller('IndexCtrl', ['$scope', function($scope){
  $scope.Model = {
    categories : ["Music", "Video"],
  }
}]) 
.controller('ListCtrl',  ['$scope', '$stateParams', function($scope, $stateParams){
  // add items to the model
  $scope.Model.items = $stateParams.category === "Music"
    ? ["Depeche Mode", "Nick Cave"]
    : ["Star Wars", "Psycho"]
  $scope.$on("$destroy", function() {delete $scope.Model.items; })
}])
.controller('DetailCtrl', ['$scope', '$stateParams', function($scope, $stateParams){
  // add item to model
  $scope.Model = { 
    item : $scope.Model.items[$stateParams.id],
  }
  $scope.$on("$destroy", function() {delete $scope.Model.item; })
}])

What is happening here? Partially we use $stateParams to change states (category is passed to List ... id into Detail)

Also all states (all the way down) do have acccess to the same instance (reference) of the $scope.Model

Check it all here

Also, what happened here, is the real use of $scope inheritance, which in UI-Router is driven by view nesting. Please, check this detailed description

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • ah ok.. thx! One question.. what would be your reason for using multiple views instead of nesting them? – Mackelito Jan 21 '15 at 07:23
  • Good question. And the answer, I'd say is - up to you. Multiple views can do some smart job, before you will select detail ... even on the "index" state, you could provide *user* with some default ("marketing" ;) stuff. There could be some content... replaced by child later. But it is up to you. I tried to put together my way... simplified. but the concept is this.. Hope it helps a bit ;) – Radim Köhler Jan 21 '15 at 08:15
  • So there is no benefits in using nested views and use services to pass data between them vs multiple views? – Mackelito Jan 21 '15 at 12:18
  • Passing data with services is not my way. Service is singleton, living for all the lifetime of the app. As I've shown you, my way is to use `$scope.Model = {}`. Such reference lives just until parent lives. So if I go to other root state, that is gone. But again.. this is up to you. Nested states support splitting index/list/detail ... multi view allow to solve separated stuff ... partilly overridable. Hope it does make sense ... – Radim Köhler Jan 21 '15 at 12:46