32

Can I set a default value of a parameter of a route in AngularJS? Is there a way to have /products/123 and /products/ handled by the same route ?

I'm looking to refactor my existing code, which looks like:

myModule.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
     when('/products/', {templateUrl: 'products.html', controller: ProductsCtrl}).            
     when('/products/:productId', {templateUrl: 'products.html', controller: ProductsCtrl})
}]);


function ProductsCtrl($scope, $routeParams) {
    $scope.productId = typeof($routeParams.productId) == "undefined" ? 123 : $routeParams.productId;
}

It works, but it's not very elegant. Is there a better way ?

4

5 回答 5

35

I recognize that this question is old, but still: Why don't you just redirect the "empty" URL to one containing the default productId?

myModule.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
     when('/products/', {redirectTo: '/products/123'}).
     when('/products/:productId', {templateUrl: 'products.html', controller: ProductsCtrl})
}]);
于 2013-10-02T02:18:29.313 回答
24

AngularJS does not allow default values for route parameters.

But routes (in AngularJS) should not have default parameters.

Resources could have default parameters.

In AngularJS if you want a route with an optional parameter, these are actually two different routes.

Why?

  • Routes should be simple

  • Routes does not allow regular expressions matching for parameters

  • Routes are not something which exposes an API to work in your application (unlike Resources do). Routes are just configuration which connects a URL with a template and a controller. Thus having more routes is better:

    • It is clear which route maps to which url.

    • It is more verbose, but simpler to read. Having more complex routes would create a steeper learning curve where AngularJS does not need one.

Unlike server-side frameworks which have routes

  • AngularJS routes do not have names.
  • You do not build URLs from the defined routes.
  • You do not have logic (a.k.a functions) in the routes definitions.

Simpler routes = more lines to define them = less headaches working with them.

NOTE: Please keep in mind the question and this answer are for an old version of AngularJS (1.0 I think) pre-dating the new routes/resources implementation.

于 2012-10-09T19:34:43.833 回答
6

I had a similar requirement. What i did was to create a function to resolve. Something like below

myModule.config(['$routeProvider', function($routeProvider) {
$routeProvider.
 when('/products/', resolveProduct()).            
 when('/products/:productId', resolveProduct())
}]);


function ProductsCtrl($scope, $routeParams) {
$scope.productId = $routeParams.productId;
}

function resolveProduct() {
   var routeConfig = {
      templateUrl: 'products.html', 
      controller: ProductsCtrl,
      resolve: {
         productId: ['$route', function($route){
            var params = $route.current.params;
            params.productId =  params.productId || 123;
         }]
      }
   }

   return routeConfig;
}
于 2014-12-03T18:30:07.460 回答
3

With url: "/view/:id/:status?", You can indicate an optional parameter.

Just thought someone may need it.

于 2016-01-06T11:26:01.377 回答
2

Not sure if this question is specific to $routeProvider but in $stateProvider, you can achieve this by

myApp.config(function($stateProvider) {

    $stateProvider
        .state('products', {
            url: '/:productId',
            templateUrl: "/dashboard/products.html",
            controller: 'ProductController',
            params: {
                productId: {
                  value: "defaultValue",
                  squash: true // or enable this instead to squash `productId` when empty
                } 
            }
        });
});
于 2016-12-20T18:16:21.077 回答