X Tutup
Skip to content

Commit a038bb9

Browse files
committed
fix(router): preserve specificity for redirects
Previously when comparing which of multiple possible routes to choose in an ambiguous case, we looked at the specificity of the target of redirect matches rather than the original match. This meant that if a redirect used a whilecard, but redirected to a target that was a static path, we'd cound the static path's specificity instead of the wildcard. This change stores the specificity of the redirect on the RedirectInstruction. Closes angular#5933
1 parent 9d28147 commit a038bb9

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

modules/angular2/src/router/instruction.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,11 @@ export class UnresolvedInstruction extends Instruction {
281281

282282
export class RedirectInstruction extends ResolvedInstruction {
283283
constructor(component: ComponentInstruction, child: Instruction,
284-
auxInstruction: {[key: string]: Instruction}) {
284+
auxInstruction: {[key: string]: Instruction}, private _specificity: string) {
285285
super(component, child, auxInstruction);
286286
}
287+
288+
get specificity(): string { return this._specificity; }
287289
}
288290

289291

modules/angular2/src/router/route_registry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export class RouteRegistry {
205205
var instruction =
206206
this.generate(candidate.redirectTo, ancestorInstructions.concat([null]));
207207
return new RedirectInstruction(instruction.component, instruction.child,
208-
instruction.auxInstruction);
208+
instruction.auxInstruction, candidate.specificity);
209209
}
210210
}));
211211

modules/angular2/test/router/integration/impl/fixture_components.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ import {
1010
} from 'angular2/router';
1111
import {PromiseWrapper} from 'angular2/src/facade/async';
1212

13+
@Component({selector: 'goodbye-cmp', template: `{{farewell}}`})
14+
export class GoodbyeCmp {
15+
farewell: string;
16+
constructor() { this.farewell = 'goodbye'; }
17+
}
18+
1319
@Component({selector: 'hello-cmp', template: `{{greeting}}`})
1420
export class HelloCmp {
1521
greeting: string;

modules/angular2/test/router/integration/redirect_route_spec.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
} from 'angular2/src/router/route_config_decorator';
2626

2727
import {TEST_ROUTER_PROVIDERS, RootCmp, compile} from './util';
28-
import {HelloCmp, RedirectToParentCmp} from './impl/fixture_components';
28+
import {HelloCmp, GoodbyeCmp, RedirectToParentCmp} from './impl/fixture_components';
2929

3030
var cmpInstanceCount;
3131
var childCmpInstanceCount;
@@ -117,5 +117,24 @@ export function main() {
117117
async.done();
118118
});
119119
}));
120+
121+
122+
it('should not redirect when redirect is less specific than other matching routes',
123+
inject([AsyncTestCompleter, Location], (async, location) => {
124+
compile(tcb)
125+
.then((rtc) => {rootTC = rtc})
126+
.then((_) => rtr.config([
127+
new Route({path: '/foo', component: HelloCmp, name: 'Hello'}),
128+
new Route({path: '/:param', component: GoodbyeCmp, name: 'Goodbye'}),
129+
new Redirect({path: '/*rest', redirectTo: ['/Hello']})
130+
]))
131+
.then((_) => rtr.navigateByUrl('/bye'))
132+
.then((_) => {
133+
rootTC.detectChanges();
134+
expect(rootTC.debugElement.nativeElement).toHaveText('goodbye');
135+
expect(location.urlChanges).toEqual(['/bye']);
136+
async.done();
137+
});
138+
}));
120139
});
121140
}

0 commit comments

Comments
 (0)
X Tutup