fix(router): routerLink support of null/undefined (#13380)
Closes #6971
This commit is contained in:
parent
9c697030e6
commit
174334dec3
|
@ -34,7 +34,7 @@ export function createUrlTree(
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMatrixParams(command: any): boolean {
|
function isMatrixParams(command: any): boolean {
|
||||||
return typeof command === 'object' && !command.outlets && !command.segmentPath;
|
return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tree(
|
function tree(
|
||||||
|
@ -70,7 +70,7 @@ class Navigation {
|
||||||
throw new Error('Root segment cannot have matrix parameters');
|
throw new Error('Root segment cannot have matrix parameters');
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmdWithOutlet = commands.find(c => typeof c === 'object' && c.outlets);
|
const cmdWithOutlet = commands.find(c => typeof c === 'object' && c != null && c.outlets);
|
||||||
if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
|
if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
|
||||||
throw new Error('{outlets:{}} has to be the last command');
|
throw new Error('{outlets:{}} has to be the last command');
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ function computeNavigation(commands: any[]): Navigation {
|
||||||
let isAbsolute = false;
|
let isAbsolute = false;
|
||||||
|
|
||||||
const res: any[] = commands.reduce((res, cmd, cmdIdx) => {
|
const res: any[] = commands.reduce((res, cmd, cmdIdx) => {
|
||||||
if (typeof cmd === 'object') {
|
if (typeof cmd === 'object' && cmd != null) {
|
||||||
if (cmd.outlets) {
|
if (cmd.outlets) {
|
||||||
const outlets: {[k: string]: any} = {};
|
const outlets: {[k: string]: any} = {};
|
||||||
forEach(cmd.outlets, (commands: any, name: string) => {
|
forEach(cmd.outlets, (commands: any, name: string) => {
|
||||||
|
@ -169,7 +169,9 @@ function createPositionApplyingDoubleDots(
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPath(command: any): any {
|
function getPath(command: any): any {
|
||||||
if (typeof command === 'object' && command.outlets) return command.outlets[PRIMARY_OUTLET];
|
if (typeof command === 'object' && command != null && command.outlets) {
|
||||||
|
return command.outlets[PRIMARY_OUTLET];
|
||||||
|
}
|
||||||
return `${command}`;
|
return `${command}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,15 +98,15 @@ export class RouterLink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set routerLink(data: any[]|string) {
|
set routerLink(commands: any[]|string) {
|
||||||
if (Array.isArray(data)) {
|
if (commands != null) {
|
||||||
this.commands = data;
|
this.commands = Array.isArray(commands) ? commands : [commands];
|
||||||
} else {
|
} else {
|
||||||
this.commands = [data];
|
this.commands = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('click', [])
|
@HostListener('click')
|
||||||
onClick(): boolean {
|
onClick(): boolean {
|
||||||
const extras = {
|
const extras = {
|
||||||
skipLocationChange: attrBoolValue(this.skipLocationChange),
|
skipLocationChange: attrBoolValue(this.skipLocationChange),
|
||||||
|
@ -163,11 +163,11 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set routerLink(data: any[]|string) {
|
set routerLink(commands: any[]|string) {
|
||||||
if (Array.isArray(data)) {
|
if (commands != null) {
|
||||||
this.commands = data;
|
this.commands = Array.isArray(commands) ? commands : [commands];
|
||||||
} else {
|
} else {
|
||||||
this.commands = [data];
|
this.commands = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1022,6 +1022,26 @@ describe('Integration', () => {
|
||||||
expect(native.getAttribute('href')).toEqual('/home');
|
expect(native.getAttribute('href')).toEqual('/home');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should not throw when commands is null', fakeAsync(() => {
|
||||||
|
@Component({
|
||||||
|
selector: 'someCmp',
|
||||||
|
template:
|
||||||
|
`<router-outlet></router-outlet><a [routerLink]="null">Link</a><button [routerLink]="null">Button</button>`
|
||||||
|
})
|
||||||
|
class CmpWithLink {
|
||||||
|
}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({declarations: [CmpWithLink]});
|
||||||
|
const router: Router = TestBed.get(Router);
|
||||||
|
|
||||||
|
let fixture: ComponentFixture<CmpWithLink> = createRoot(router, CmpWithLink);
|
||||||
|
router.resetConfig([{path: 'home', component: SimpleCmp}]);
|
||||||
|
const anchor = fixture.nativeElement.querySelector('a');
|
||||||
|
const button = fixture.nativeElement.querySelector('button');
|
||||||
|
expect(() => anchor.click()).not.toThrow();
|
||||||
|
expect(() => button.click()).not.toThrow();
|
||||||
|
}));
|
||||||
|
|
||||||
it('should update hrefs when query params or fragment change', fakeAsync(() => {
|
it('should update hrefs when query params or fragment change', fakeAsync(() => {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
Loading…
Reference in New Issue