Skip to content

Commit e8cff9b

Browse files
authored
feat(router): add ability to unregister a route (#60)
Closes #49
1 parent 1b868fd commit e8cff9b

File tree

3 files changed

+76
-4
lines changed

3 files changed

+76
-4
lines changed

README.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ yarn add angular-routing
2626

2727
## Installation with ng add
2828

29-
You can use ng add to install the package by using below command.
29+
You can use ng add to install the package by using the command below.
3030

3131
```sh
3232
ng add angular-routing
@@ -85,6 +85,62 @@ After your components are registered, use the `Router` and `Route` components to
8585
</router>
8686
```
8787

88+
## Route sorting
89+
90+
Angular routing is sorting the routes upon registration, based on priority. The order in which the routes are defined in your template is therefore not important.
91+
92+
The following two examples will give the same results
93+
94+
```html
95+
<router>
96+
<route path="/blog" [exact]="false">
97+
<app-blog *routeComponent></app-blog>
98+
</route>
99+
<route path="/" redirectTo="/blog"></route>
100+
<route path="/" [exact]="false">
101+
<app-page-not-found *routeComponent></app-page-not-found>
102+
</route>
103+
</router>
104+
```
105+
106+
and
107+
108+
```html
109+
<router>
110+
<route path="/" [exact]="false">
111+
<app-page-not-found *routeComponent></app-page-not-found>
112+
</route>
113+
<route path="/" redirectTo="/blog"></route>
114+
<route path="/blog" [exact]="false">
115+
<app-blog *routeComponent></app-blog>
116+
</route>
117+
</router>
118+
```
119+
120+
The sorting algorithm has only a few rules (ordered by importance):
121+
122+
- Named routes (e.g. `/blog`) have priority over root route (`/`)
123+
- Static routes (e.g. `/blog/view`) have priority over parametrized (e.g. `/blog/:id`)
124+
- Exact route (with `exact` set to `true` or omitted) has priority over non-exact (with `exact` set to `false`)
125+
- Longer paths have priority over shorter
126+
127+
## Route restrictions
128+
129+
Implementing the route restriction is as simple as adding a structural directive on a `route` component
130+
131+
```html
132+
<router>
133+
<route path="/admin" *ngIf="user.isAuthenticated$ | async">
134+
<app-admin *routeComponent></app-admin>
135+
</route>
136+
<route path="/admin" *ngIf="!(user.isAuthenticated$ | async)">
137+
<app-login *routeComponent></app-login>
138+
</route>
139+
</router>
140+
```
141+
142+
The restriction doesn't stop the navigation. It simply removes the route from the configuration so the next eligible route will pick it up.
143+
88144
## Navigating with Links
89145

90146
Use the `linkTo` directive with a _full path_ to register links handled by the router.

libs/angular-routing/src/lib/route.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ export class RouteComponent implements OnInit, OnDestroy {
161161
}
162162

163163
ngOnDestroy() {
164+
this.routerComponent.unregisterRoute(this.route);
164165
this.destroy$.next();
165166
}
166167

libs/angular-routing/src/lib/router.component.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ interface State {
2626
routes: Route[];
2727
}
2828

29+
type UnregisterableRoute = Route & { unregister?: boolean };
30+
2931
@Component({
3032
// tslint:disable-next-line:component-selector
3133
selector: 'router',
@@ -115,9 +117,7 @@ export class RouterComponent implements OnInit, OnDestroy {
115117
});
116118

117119
route.matcher = route.matcher || routeRegex;
118-
119-
const routes = this.state$.value.routes;
120-
this.updateState({ routes: routes.concat(route).sort(compareRoutes) });
120+
this.updateRoutes(route);
121121

122122
return route;
123123
}
@@ -126,6 +126,10 @@ export class RouterComponent implements OnInit, OnDestroy {
126126
this.updateState({ activeRoute });
127127
}
128128

129+
unregisterRoute(route: Route) {
130+
this.updateRoutes({ ...route, unregister: true });
131+
}
132+
129133
normalizePath(path: string) {
130134
return this.router.normalizePath(path);
131135
}
@@ -155,4 +159,15 @@ export class RouterComponent implements OnInit, OnDestroy {
155159
private updateState(newState: Partial<State>) {
156160
this.state$.next({ ...this.state$.value, ...newState });
157161
}
162+
163+
private updateRoutes(route: UnregisterableRoute) {
164+
const routes = this.state$.value.routes;
165+
if (route.unregister) {
166+
this.updateState({
167+
routes: routes.filter((r) => r.matcher !== route.matcher),
168+
});
169+
} else {
170+
this.updateState({ routes: routes.concat(route).sort(compareRoutes) });
171+
}
172+
}
158173
}

0 commit comments

Comments
 (0)