-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BREAKING CHANGE: Order URL Matching Rules by priority, not registrati…
…on order URL Rules can come from registered states' `.url`s, calling `.when()`, or calling `.rule()`. It's possible that two or more URL Rules could match the URL. ### Previously Previously, url rules were matched in the order in which they were registered. The rule which was registered first would handle the URL change. ### Now Now, the URL rules are sorted according to a sort function. More specific rules are preferred over less specific rules ### Why It's possible to have multiple url rules that match a given URL. Consider the following states: - `{ name: 'books', url: '/books/index' }''` - `{ name: 'book', url: '/books/:bookId' }''` Both states match when the url is `/books/index`. Additionally, you might have some custom url rewrite rules such as: `.when('/books/list', '/books/index')`. The `book` state also matches when the rewrite rule is matched. Previously, we simply used the first rule that matched. However, now that lazy loading is officially supported, it can be difficult for developers to ensure the rules are registered in the right order. Instead, we now prioritize url rules by how specific they are. More specific rules are matched earlier than less specific rules. We split the path on `/`. A static segment (such as `index` in the example) is more specific than a parameter (such as`:bookId`). ### More Details The built-in rule sorting function (see `UrlRouter.defaultRuleSortFn`) sorts rules in this order: - Explicit priority: `.when('/foo', '/bar', { priority: 1 })` (default priority is 0) - Rule Type: - UrlMatchers first (registered states and `.when(string, ...)`) - then regular Expressions (`.when(regexp, ...)`) - finally, everything else (`.rule()`) - UrlMatcher specificity: static path segments are more specific than variables (see `UrlMatcher.compare`) - Registration order (except for UrlMatcher based rules) For complete control, a custom sort function can be registered with `UrlService.rules.sort(sortFn)` ### Query params Because query parameters are optional, they are not considered during sorting. For example, both these rules will match when the url is `'/foo/bar'`: ``` .when('/foo/bar', doSomething); .when('/foo/bar?queryparam', doSomethingElse); ``` To choose the most specific rule, we match both rules, then choose the rule with the "best ratio" of matched optional parameters (see `UrlRuleFactory.fromUrlMatcher`) This allows child states to be defined with only query params for a URL. The state only activates when the query parameter is present. ``` .state('parent', { url: '/parent' }); .state('parent.child', { url: '?queryParam' }); ``` ## Restoring the previous behavior For backwards compatibility, register a sort function which sorts by the registration order: ```js myApp.config(function ($urlServiceProvider) { function sortByRegistrationOrder(a, b) { return a.$id - b.$id; } $urlServiceProvider.rules.sort(sortByRegistrationOrder); }); ``` --- feat(UrlRouter): sort url rules by specificity, not by registration order. refactor(UrlMatcher): Include own matcher in matcher._cache.path feat(UrlMatcher): Add comparison function by UrlMatcher specificity refactor(UrlRule): Use interface for UrlRules instead of extending classes
- Loading branch information
1 parent
7334d98
commit eb2f5d7
Showing
13 changed files
with
852 additions
and
414 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.