Angular multiple routes sharing one controller

I'm not sure if I am approaching this correctly, but I am building an ecommerce site. There are 6 different product grid pages in the site part, each of which can use the same look:

<ul class="products row">
    <li class="product thumbnail col-1 grid" ng-repeat="whisky in whiskies | orderBy: sort">
        <p class="picture">
            <a ng-href="#/json/{{whisky.id}}"><img ng-src="images/scotch/{{whisky.imageUrl}}" alt="{{whisky.name}}"/></a>
        </p>
        <div class="desc">
            <h2>{{whisky.name}}</h2>
            <p class="price"><span>&pound;{{whisky.price}}</span></p>
        </div>
        <div class="actions">    
        <button class="add-to-basket btn btn-primary btn-medium fa fa-shopping-cart" data-item='{"imageUrl" : "{{whisky.imageUrl}}", "price" : "{{whisky.price}}", "startPrice" : "{{whisky.price}}", "name" : "{{whisky.name}}", "totalItems" : "{{1}}"}' ng-click="updateMiniBasket($event)"></button>    
        </div>
    </li>
</ul>

      

and the same controller:

whiskyControllers.controller('whiskyListCtrlr', ['$scope', 'whiskyList', '$http', 

    function($scope, whiskyList, $http){

        whiskyList.getWhiskies().then(function(d) {
            $scope.whiskies = d.data;
        })

    }

])

      

but you need to have a different route in the route provider config, i.e. one goes to scotch, one goes to Irish, one to Japanese, etc.

How do I code the routing so that different pages have the same controller and view? Is it possible to pass parameters from router to controller?

Many thanks

+3


source to share


2 answers


Yes, you can reuse controllers and views as often as you like. If I understand you correctly, you want to use different routes to use the same controller and view? It's simple. Also, do you want to be able to pass variables to your controller when you run a route? Also easy. Here's an example that doesn't use ui-router

.

angular.module('myApp').config(['$routeProvider', 'whiskeyList', appConfig]); 

function appConfig($routeProvider, wiskeyList) {
  $routeProvider
  .when('/scotch', {
    controller: 'whiskeyListCtrlr',
    resolve: {
      data: function(whiskeyList) {
        return whiskeyList.getWhiskeys();
      }
    }
  })
  .when('/irish', {
    controller: 'whiskeyListCtrlr',
    resolve: {
      data: function(whiskeyList) {
        return whiskeyList.getWhiskeys();
      }
    }
  });
}

      

Obviously this implementation is not DRY (don't repeat yourself). I would revisit your implementation. I would change whiskeyList.getWhiskeys()

to accept a parameter that tells it the type of whiskey to return. Eg whiskeyList.getWhiskeys('scotch')

. Then, the data you get in the controller is filtered only for what it needs to view.



The data displayed in the router's resolution function is available in the controller by name.

whiskyControllers.controller('whiskyListCtrlr', ['$scope', 'data', function ($scope, data) {
  $scope.whiskeys = data;
});

      

+7


source


It is fairly easy to do this with ui-router , which has many advantages over native routing in angular. Ui Router allows you to encapsulate states by specifying a template and controller, and "allow" data (based on route or other parameters) that can then be passed to controllers. Something like the following will work well for you:

angular.module('whiskyApp')
    .config(['$stateProvider', function($stateProvider) {
        $stateProvider
        .state('whiskyList', {

             // whisky-type is a catch all here - can be 'irish', 'japanese', anything.
             // can also use regex to restrict it a bit
             url: '/lists/:whiskyType',
             templateUrl: 'whisky-list-template.html',
             controller: 'whiskyListCtrl',

             // this is what gets passed to the controller
             resolve: {
                 type: ['$stateParams', function($stateParams) {

                     // pass the whisky type from the url into the controller
                     return $stateParams.whiskyType;
                 }],
                 list: ['$stateParams', 'whiskyList', function($stateParams, whiskyList) {

                     // we can also go ahead and pass in the resolved list - this is best practice
                     return whiskyList.getWhiskies();
                 }]
             }
        });
    }]);

]);

      



And then in your controller just enter the name of the map keys "permission" to use them:

whiskyControllers.controller('whiskyListCtrlr', ['$scope', 'list', 'type' '$http', 

    function($scope, list, type, $http){
       $scope.whiskies = list;
       $scope.type = type;
    }
])

      

+5


source







All Articles