angular multiple routes sharing one controller

核能气质少年 提交于 2019-12-21 20:39:35

问题


I'm not sure if I'm approaching this correctly but I'm building an ecommerce site - part of the site has 6 different product grid pages, each of which can use the same view:

<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 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 the different pages share the same controller and view? Is it maybe possible to pass parameters from the router to the controller?

Many thanks


回答1:


Yes, you can reuse controllers and views as often as you want. If I understand you correctly, you want different routes to use the same controller and view? That's easy. Additionally, you want to be able to pass variables to your controller when the route is triggered? Also easy. Here is an example that does not 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 rethink your implementation. I would change whiskeyList.getWhiskeys() to accept a parameter that tells it the type of whiskey to return. For example, whiskeyList.getWhiskeys('scotch'). Then, the data you receive in your controller is filtered to only what the view requires.

The data mapped in the router's resolve function is accessed in the controller by name.

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



回答2:


This is pretty easy to do with ui-router, which offers many advantages over the built in routing in angular. Ui Router allows you to encapsulate states by specifying a template and controller, and "resolve" data (based off of route or other parameters) which you can then pass into your controllers. Something like the following would 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 contoller, just inject the name of keys of the 'resolve' map to use them:

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

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


来源:https://stackoverflow.com/questions/27493495/angular-multiple-routes-sharing-one-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!