diff --git a/packages/router/src/operators/activate_routes.ts b/packages/router/src/operators/activate_routes.ts index 094da9649c..8abe7300f1 100644 --- a/packages/router/src/operators/activate_routes.ts +++ b/packages/router/src/operators/activate_routes.ts @@ -123,6 +123,11 @@ export class ActivateRoutes { context.outlet.deactivate(); // Destroy the contexts for all the outlets that were in the component context.children.onOutletDeactivated(); + // Clear the information about the attached component on the context but keep the reference to + // the outlet. + context.attachRef = null; + context.resolver = null; + context.route = null; } } diff --git a/packages/router/test/regression_integration.spec.ts b/packages/router/test/regression_integration.spec.ts index 9dd5b8ba32..84b5117c5e 100644 --- a/packages/router/test/regression_integration.spec.ts +++ b/packages/router/test/regression_integration.spec.ts @@ -7,7 +7,7 @@ */ import {CommonModule} from '@angular/common'; -import {ChangeDetectionStrategy, Component, ContentChild, NgModule, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; +import {ChangeDetectionStrategy, ChangeDetectorRef, Component, NgModule, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; import {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; import {Router} from '@angular/router'; import {RouterTestingModule} from '@angular/router/testing'; @@ -187,6 +187,46 @@ describe('Integration', () => { expect(fixture.nativeElement.innerHTML).toContain('isActive: true'); })); }); + + it('should not reactivate a deactivated outlet when destroyed and recreated - #41379', + fakeAsync(() => { + @Component({template: 'simple'}) + class SimpleComponent { + } + + @Component({template: ` `}) + class AppComponent { + outletVisible = true; + } + + TestBed.configureTestingModule({ + imports: [RouterTestingModule.withRoutes( + [{path: ':id', component: SimpleComponent, outlet: 'aux'}])], + declarations: [SimpleComponent, AppComponent], + }); + + const router = TestBed.inject(Router); + const fixture = createRoot(router, AppComponent); + const componentCdr = fixture.componentRef.injector.get(ChangeDetectorRef); + + router.navigate([{outlets: {aux: ['1234']}}]); + advance(fixture); + expect(fixture.nativeElement.innerHTML).toContain('simple'); + + router.navigate([{outlets: {aux: null}}]); + advance(fixture); + expect(fixture.nativeElement.innerHTML).not.toContain('simple'); + + fixture.componentInstance.outletVisible = false; + componentCdr.detectChanges(); + expect(fixture.nativeElement.innerHTML).not.toContain('simple'); + expect(fixture.nativeElement.innerHTML).not.toContain('router-outlet'); + + fixture.componentInstance.outletVisible = true; + componentCdr.detectChanges(); + expect(fixture.nativeElement.innerHTML).toContain('router-outlet'); + expect(fixture.nativeElement.innerHTML).not.toContain('simple'); + })); }); function advance(fixture: ComponentFixture): void {