Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support of redirectTo instruction at segment params. #16

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

wingedfox
Copy link
Contributor

Useful for managing external and internal redirects within a route definitions

Syntax:

$routeSegmentProvider
    .when('/section', 's1')
    .when('/section/index', 's1.idx')
    .segment('section', {
         redirectTo: 'section/index'
     })
    .within()
        .segment('idx', {
             templateUrl: '/views/segment/idx.html'
         });

Syntax:
$routeSegmentProvider
    .when('/section', 's1')
    .when('/section/index', 's1.idx')
    .segment('section', {
         redirectTo: 'section/index'
     })
    .within()
        .segment('idx', {
             templateUrl: '/views/segment/idx.html'
         });
 * multiple views per segment, based on the dependencies
 * support for ng-if, ng-switch and other directives based on the transclusion
 * scope-based segment names

Example:
Routes:
```javascript
$routeSegmentProvider
    .when('/page', 'page')
    .when('/page/:view1,:view2', 'page.view')
    .when('/page/:view1', 'page.view')
    .segment('page', {
        redirectTo: '/page/main',
        templateUrl : '/views/layout/page.html',
        controller  : 'PageCtrl'
    })
    .within()
        .segment('view', {
            dependencies : ['view1', 'view2'],
            templateUrl : {
                main  : '/views/page/main.html',
                other : '/views/page/other.html',
                more  : '/views/more.html'
            },
            controller  : {
                main  : 'MainCtrl',
                other : 'TextCtrl',
                more  : 'ChartCtrl'
            }
        });
```
View:
```html
<div class="page"
 <div class="view" ng-class="{left: isDouble(), main: isSingle()}">
  <div class="content" app-view-segment="segment1"></div>
 </div>
 <div class="right view" ng-if="isDouble()">
  <div class="frame" app-view-segment="segment2"></div>
 </div>
</div>
```
Controller:
```javascript
function($rootScope, $scope, $location, $routeSegment, $routeParams, $animate) {
  $scope.$watch(function () {return $routeParams}, function (n, o) {
    $scope.$windowMode = (n.window1 && n.window2) ? 2 : 1;
  }, true);

  $scope.segment1 = '1.view1';
  $scope.segment2 = '1.view2';

  /**
   *  @return {Boolean} - true if only one window is enabled
   */
  $scope.isSingle = function isSingle () {
    return $scope.$windowMode == 1;
  }

  /**
   *  @return {Boolean} - true if two windows are enabled
   */
  $scope.isDouble = function isDouble () {
    return $scope.$windowMode == 2;
  }
}
```
@chmanie
Copy link

chmanie commented Dec 17, 2013

Great work!
Right now I'm creating a separate controller for every route I want to redirect to.
It'd be really nice to see this merged. But I think you might have to add tests for this to happen...

@artch
Copy link
Owner

artch commented Dec 18, 2013

@wingedfox Your provided example could be easily rewrited like this:

$routeSegmentProvider
    .when('/section', 's1.idx')  // you can use deep-level segment here
    .when('/section/index', 's1.idx')
    .segment('section', {
         template: '<div app-view-segment="1"></div>'
     })
    .within()
        .segment('idx', {
             templateUrl: '/views/segment/idx.html'
         });

There is no need in separate redirectTo functionality for such a case. Also, you can use $routeProvider's redirecting as well:

$routeProvider.when('/invalidUrl', {redirectTo: '/validUrl'});
$routeSegmentProvider.when('/validUrl', 'segment')
.segment('segment', ...);

But your latter commits look really interesting. Could you please provide tests on it?

@wingedfox
Copy link
Contributor Author

@artch, even if I can buy a piglet, I prefer not to do that :) In your example you'll have all the relative links broken.
Redirects in my example are used for hiding gaps in the navigation tree, I prefer to cover them by local redirects instead of a global ones.
E.g. at a given time I have a mapping

/    -> /a
/a   -> /a/b
/a/b -> /a/b/c

for sure this does not mean that the following will be correct at any given moment

/  -> /a/b/c
/a -> /a/b/c

when a root page is added inner redirects will remain intact.

I'll try to add the tests, but I don't work on that project anymore so first I'll have to remember what's going on there.
Anyway, it will take a place not before the mid-january, because I'll be on a vacation.

@artch
Copy link
Owner

artch commented Dec 19, 2013

A bit unclear for me. You wrote:

$routeSegmentProvider
    .when('/section', 's1')
    .when('/section/index', 's1.idx')
    .segment('section', {
         redirectTo: 'section/index'
     })

This piece of configuration is identical to:

$routeSegmentProvider
    .when('/section', 's1.idx')  
    .when('/section/index', 's1.idx')

Isn't it?

@wingedfox
Copy link
Contributor Author

Following your way link from template

<a href="b" />

with /section in the address bar it will point to /b
with /section/index in the address bar it will point to /section/b

When using redirects, you'll never see /section in the address bar, you always will be redirected to /section/index.

@artch
Copy link
Owner

artch commented Dec 19, 2013

OK, why not to use built-in angular $routeProvider.when('/section', {redirectTo: '/section/index'}) for this case? I really see no reason for implementing redirects at segments level of abstraction.

@wingedfox
Copy link
Contributor Author

For me, this is the vital case.
Without this feature I'll have the dozens of

$routeProvider.when('/section', {redirectTo: '/section/index'})

instructions, placed somewhere out of context, where the section is defined.
Take a look:

$routeProvider.when('/', {redirectTo: '/reports/market/au/slices'})
$routeProvider.when('/reports', {redirectTo: '/reports/market/au/slices'})
$routeProvider.when('/reports/market', {redirectTo: '/reports/market/au/slices'})
$routeProvider.when('/reports/market/au', {redirectTo: '/reports/market/au/slices'})
$routeProvider.when('/reports/market/value', {redirectTo: '/reports/market/value/sum'})

Here I have to change 3 lines to make /reports/market/value/sum default report.
With per-segment redirects I'll have to change only one line.
I have a script for building the routing table for the reports and I'll prefer to generate as few lines as possible.

@artch
Copy link
Owner

artch commented Dec 19, 2013

I see. How do you assign segments to URLs in the case of these 5 routes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants