feat(router): add new initialNavigation options to replace legacy (#37480)

As of Angular v4, four of the options for
`ExtraOptions#initialNavigation` have been deprecated. We intend
to remove them in v11. The final state for these options is:
`enabledBlocking`, `enabledNonBlocking`, and `disabled`. We plan
to remove and deprecate the remaining option in the next two
major releases.

New options:
- `enabledNonBlocking`: same as legacy_enabled
- `enabledBlocking`: same as enabled

BREAKING CHANGE:

* The `initialNavigation` property for the options in
  `RouterModule.forRoot` no longer supports `legacy_disabled`,
  `legacy_enabled`, `true`, or `false` as valid values.
  `legacy_enabled` (the old default) is instead `enabledNonBlocking`
* `enabled` is deprecated as a valid value for the
  `RouterModule.forRoot` `initialNavigation` option. `enabledBlocking`
  has been introduced to replace it

PR Close #37480
This commit is contained in:
Adam
2020-06-07 18:01:11 -05:00
committed by atscott
parent b0a8b69ae8
commit c4becca0e4
4 changed files with 104 additions and 84 deletions

View File

@ -95,7 +95,44 @@ describe('bootstrap', () => {
});
});
it('should NOT wait for resolvers to complete when initialNavigation = legacy_enabled',
it('should wait for resolvers to complete when initialNavigation = enabledBlocking', (done) => {
@Component({selector: 'test', template: 'test'})
class TestCmpEnabled {
}
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(
[{path: '**', component: TestCmpEnabled, resolve: {test: TestResolver}}],
{useHash: true, initialNavigation: 'enabledBlocking'})
],
declarations: [RootCmp, TestCmpEnabled],
bootstrap: [RootCmp],
providers: [...testProviders, TestResolver],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
class TestModule {
constructor(router: Router) {
log.push('TestModule');
router.events.subscribe(e => log.push(e.constructor.name));
}
}
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
const router = res.injector.get(Router);
const data = router.routerState.snapshot.root.firstChild!.data;
expect(data['test']).toEqual('test-data');
expect(log).toEqual([
'TestModule', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart',
'ChildActivationStart', 'ActivationStart', 'GuardsCheckEnd', 'ResolveStart', 'ResolveEnd',
'RootCmp', 'ActivationEnd', 'ChildActivationEnd', 'NavigationEnd', 'Scroll'
]);
done();
});
});
it('should NOT wait for resolvers to complete when initialNavigation = enabledNonBlocking',
(done) => {
@Component({selector: 'test', template: 'test'})
class TestCmpLegacyEnabled {
@ -106,7 +143,7 @@ describe('bootstrap', () => {
BrowserModule,
RouterModule.forRoot(
[{path: '**', component: TestCmpLegacyEnabled, resolve: {test: TestResolver}}],
{useHash: true, initialNavigation: 'legacy_enabled'})
{useHash: true, initialNavigation: 'enabledNonBlocking'})
],
declarations: [RootCmp, TestCmpLegacyEnabled],
bootstrap: [RootCmp],
@ -137,6 +174,47 @@ describe('bootstrap', () => {
});
});
it('should NOT wait for resolvers to complete when initialNavigation is not set', (done) => {
@Component({selector: 'test', template: 'test'})
class TestCmpLegacyEnabled {
}
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(
[{path: '**', component: TestCmpLegacyEnabled, resolve: {test: TestResolver}}],
{useHash: true})
],
declarations: [RootCmp, TestCmpLegacyEnabled],
bootstrap: [RootCmp],
providers: [...testProviders, TestResolver],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
class TestModule {
constructor(router: Router) {
log.push('TestModule');
router.events.subscribe(e => log.push(e.constructor.name));
}
}
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
const router: Router = res.injector.get(Router);
expect(router.routerState.snapshot.root.firstChild).toBeNull();
// ResolveEnd has not been emitted yet because bootstrap returned too early
expect(log).toEqual([
'TestModule', 'RootCmp', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart',
'ChildActivationStart', 'ActivationStart', 'GuardsCheckEnd', 'ResolveStart'
]);
router.events.subscribe((e) => {
if (e instanceof NavigationEnd) {
done();
}
});
});
});
it('should not run navigation when initialNavigation = disabled', (done) => {
@Component({selector: 'test', template: 'test'})
class TestCmpDiabled {
@ -168,37 +246,6 @@ describe('bootstrap', () => {
});
});
it('should not run navigation when initialNavigation = legacy_disabled', (done) => {
@Component({selector: 'test', template: 'test'})
class TestCmpLegacyDisabled {
}
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(
[{path: '**', component: TestCmpLegacyDisabled, resolve: {test: TestResolver}}],
{useHash: true, initialNavigation: 'legacy_disabled'})
],
declarations: [RootCmp, TestCmpLegacyDisabled],
bootstrap: [RootCmp],
providers: [...testProviders, TestResolver],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
class TestModule {
constructor(router: Router) {
log.push('TestModule');
router.events.subscribe(e => log.push(e.constructor.name));
}
}
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
const router = res.injector.get(Router);
expect(log).toEqual(['TestModule', 'RootCmp']);
done();
});
});
it('should not init router navigation listeners if a non root component is bootstrapped',
(done) => {
@NgModule({