Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular ui router multiple views with route(state) parameters

I have a page where I show 2 different lists of products using multiple views with each having a controller and template file. My state definition is like this:

    .state('all_lists', {
      url: '/lists',
      views: {
      '' : {templateUrl: 'my-lists.html'},
      'featured@all_lists' : {templateUrl: 'featured.html', controller: 'featuredCtrl'},
      'deals@all_lists' : {templateUrl: 'deals.html', controller: 'dealsCtrl'}
      }
     }
    )

Each individual list has pagination and sorting filters at the top and these pagination and sorting filters are added to the URL as state parameters. Please tell me how to define these parameters for views of a state so that they can be added to URL and then used in the respective controllers.

If you have any better idea of displaying such a list of products with pagination parameters added to URL, please share your ideas. Any help will be greatly appreciated.

Thanks

NOTE: Please note that, I need to display both the lists on 1 page. Its kind of a homepage and featured Items list and then below that hot deals Items list is displayed and both of these lists have pagination, sorting and few other filters. URL will be something like this. mydomain.com/products/featured-page_1/deals-page_2/perpage_10/

NOTE 2: After researching a lot and investigating, I have found out that this a clear case of Parallel States. Please tell me how to implement parallel states using the URL parameters scheme I am using currently.

<html>
  <head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    </head>
  <body>
    <div id="content">
      <h1>Products Homepage</h1>
      <h3>Some common filters for both lists</h3>
    <div id="featured">
      <h2>Featured List</h2>
      <div>pagination and other filters</div>
      <ul>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        <li>item 4</li>
        <li>item 5</li>
      </ul>
      </div>
      <div id="deals">
        <h2>Hot Deals List</h2>
      <div>pagination and other filters for hot deals</div>
      <ul>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        <li>item 4</li>
        <li>item 5</li>
      </ul>
      </div>
    </div>
    </body>
  </html>
like image 525
Abdul Haseeb Avatar asked Nov 08 '16 13:11

Abdul Haseeb


2 Answers

Instead of having it as multiple views, Have them as child views with parent being abstract. Look at the code below,

$stateProvider
    .state("product", {
        url: '/product',
        templateUrl: "/Views/productHome.html",
        abstract: true,
        controller: "productHomeCtrl"
    })
    .state('product.thumbnailview', {
        url: '/producttv',
        templateUrl: "/Views/thumbnailview.html",
        controller: "thumbnailViewCtrl",
        params: {
            param1: null,
            param2: null
        }
    })
    .state('product.listview', {
        url: '/productlv',
        templateUrl: "Views/listview",
        controller: "listViewCtrl",
        params: {
            param1: null,
            param2: null
        }
    })

Now you can use the params by injecting stateParams service separately in your respective controllers. Note: Also your product State can never have stateParams at all.

Note: But if you try to reach to product state directly it will not get activated because it is abstract state How ever you can handle pagination by having the markup in either productHome.html globally or the respective views.

If your keeping the pagination in productHome.html you can still access the productDetails array using $scope.$parent.productList and reuse the same scope variable.

So in this case you will your productHome.html will like this

<div> 
    <div > MENU OPTIONS </div>
    <div ng-view>   </div>
    <ul uib-pagination total-items="itemLength" ng-model="currentPage" ng-change="pageChanged()"></ul>
</div>

These three objects can be handled in any of the three controllers

  1. itemLength
  2. currentPage
  3. pageChanged()

Both thumbnails and list view will contain markups for the layout purpose only.

<div>
    <div> Thumbnail or List markup </div> very simple you can play with bootstrap grid layout.
</div

Update 1

For a route like this

//mydomain.com/products/featured-page_1/deals-age_2/perpage‌​_10/

Using my solution you can handle it something like this

//mydomain.com/products/featured/page_1/deals/age_2/

So your child states will be

$stateProvider
    .state("product", {
        url: '/product',
        templateUrl: "/Views/productHome.html",
        abstract: true,
        controller: "productHomeCtrl"
    })
    .state('product.featured/', {
        url: '/featured/:number',
        templateUrl: "/Views/featured.html",
        controller: "featuredCtrl",
        params: {
            number: null,
        }
    })
    .state('product.deals', {
        url: '/deals/:number',
        templateUrl: "Views/deals.html",
        controller: "dealsCtrl",
        params: {
            number: null
        }
})

In the featuredCtrl you can access those parameters using

$stateParam.number

In the dealsCtrl you can access those parameters using

$stateParam.number

Have the perpage value in the $rootscope or in the productHomeCtrl

like image 173
Aravind Avatar answered Nov 06 '22 19:11

Aravind


You just need to specify the params on the url and call them in the controller

.state('all_lists', {
  url: '/lists?dealPage&featPage&otherParam',
  views: {
  '' : {templateUrl: 'my-lists.html'},
  'featured@all_lists' : {templateUrl: 'featured.html', controller: 'featuredCtrl'},
  'deals@all_lists' : {templateUrl: 'deals.html', controller: function($scope, $stateParams) {
     $scope.page= $stateParams.dealPage;
     $scope.otherParam= $stateParams.otherParam;
  }}
  }
 }
)
like image 45
Yumarx Polanco Avatar answered Nov 06 '22 18:11

Yumarx Polanco