dotJEM / angular-routing

Enhanced state based routing for Angular applications!
https://dotjem.github.io/angular-routing/
MIT License
75 stars 9 forks source link

Asterisk is too greedy in route matching #117

Open thorn0 opened 10 years ago

thorn0 commented 10 years ago

Can't figure out how I should configure states/routes to get what I need.

I need that URLs like folder1/filename, folder1/folder2/filename be matched to one state (say file), and URLs like folder1/filename/EDIT, folder1/folder2/filename/EDIT to another (file.edit). As it might include any number of folders, I use a parameter with asterisk to match the folders and file name:

$stateProvider.state('file', { route: '{*path}' });

But then, I can't configure the file.edit state:

$stateProvider.state('file.edit', { route: '/EDIT' });

It doesn't work as /EDIT becomes part of the path parameter. Can something be done here? Can the asterisk be less greedy?

jeme commented 10 years ago

Unfortunately the routing system doesn't support that, when you add a catch all parameter we eat up the rest of the url, and I can't find a sane way to otherwise deal with that in your specific case where you will end up having a very dynamic url in front of your "/EDIT" part of your path.

There is a way to achieve this though, but it's actually quite ugly. Given this plunker: http://plnkr.co/edit/O6XfQFyUzZHlOzcLRgRZ?p=preview

We can register a converter to deal with this:

    String.prototype.endsWith = function(suffix) {
      return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };

    $routeProvider.convert('isNotEdit', function() {
      return {
        parse: function(param) {
          return !param.endsWith('EDIT');
        }
      };
    });

(it's actually possible that you can use the "regex" converter out of the box to achieve this, but this was just done quickly.)

Now you can use those in your states:

$stateProvider.state('file', { route: '{isNotEdit:*path}' });
$stateProvider.state('file.edit', { route: '/EDIT' });

This isn't ideal as it's really due to a side effect that this works. I will think about how this could be added in a better way.

thorn0 commented 10 years ago

I will think about how this could be added in a better way.

Seems that a possible solution is to try matching substates first, before the parent state.

jeme commented 10 years ago

@thorn0 It's designed so the Routing engine is a standalone component, meaning it doesn't have any knowledge of that.

Besides, your also looking for the ability to configure routes as: /{*}/Something/More, which is more complex than just so...