fix(router): support outlets within dynamic components
Fixes internal b/27294172
This commit is contained in:

committed by
Vikram Subramanian

parent
75343eb340
commit
7d44b8230e
@ -9,6 +9,12 @@ import {
|
||||
ROUTER_DIRECTIVES
|
||||
} from 'angular2/router';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {
|
||||
DynamicComponentLoader,
|
||||
ComponentRef
|
||||
} from 'angular2/src/core/linker/dynamic_component_loader';
|
||||
import {ElementRef} from 'angular2/src/core/linker/element_ref';
|
||||
|
||||
@Component({selector: 'goodbye-cmp', template: `{{farewell}}`})
|
||||
export class GoodbyeCmp {
|
||||
@ -135,3 +141,31 @@ export function asyncRouteDataCmp() {
|
||||
@RouteConfig([new Redirect({path: '/child-redirect', redirectTo: ['../HelloSib']})])
|
||||
export class RedirectToParentCmp {
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'dynamic-loader-cmp', template: `{ <div #viewport></div> }`})
|
||||
@RouteConfig([new Route({path: '/', component: HelloCmp})])
|
||||
export class DynamicLoaderCmp {
|
||||
private _componentRef: ComponentRef = null;
|
||||
constructor(private _dynamicComponentLoader: DynamicComponentLoader,
|
||||
private _elementRef: ElementRef) {}
|
||||
|
||||
onSomeAction(): Promise<any> {
|
||||
if (isPresent(this._componentRef)) {
|
||||
this._componentRef.dispose();
|
||||
this._componentRef = null;
|
||||
}
|
||||
return this._dynamicComponentLoader.loadIntoLocation(DynamicallyLoadedComponent,
|
||||
this._elementRef, 'viewport')
|
||||
.then((cmp) => { this._componentRef = cmp; });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'loaded-cmp',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
class DynamicallyLoadedComponent {
|
||||
}
|
||||
|
@ -17,7 +17,16 @@ import {specs, compile, TEST_ROUTER_PROVIDERS, clickOnElement, getHref} from '..
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
import {Router, Route, Location} from 'angular2/router';
|
||||
|
||||
import {HelloCmp, UserCmp, TeamCmp, ParentCmp, ParentWithDefaultCmp} from './fixture_components';
|
||||
import {
|
||||
HelloCmp,
|
||||
UserCmp,
|
||||
TeamCmp,
|
||||
ParentCmp,
|
||||
ParentWithDefaultCmp,
|
||||
DynamicLoaderCmp
|
||||
} from './fixture_components';
|
||||
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
|
||||
function getLinkElement(rtc: ComponentFixture) {
|
||||
@ -420,6 +429,55 @@ function syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams() {
|
||||
}));
|
||||
}
|
||||
|
||||
function syncRoutesWithDynamicComponents() {
|
||||
var fixture;
|
||||
var tcb;
|
||||
var rtr: Router;
|
||||
|
||||
beforeEachProviders(() => TEST_ROUTER_PROVIDERS);
|
||||
|
||||
beforeEach(inject([TestComponentBuilder, Router], (tcBuilder, router) => {
|
||||
tcb = tcBuilder;
|
||||
rtr = router;
|
||||
}));
|
||||
|
||||
|
||||
it('should work',
|
||||
inject([AsyncTestCompleter],
|
||||
(async) => {tcb.createAsync(DynamicLoaderCmp)
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([new Route({path: '/', component: HelloCmp})]))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('{ }');
|
||||
return fixture.componentInstance.onSomeAction();
|
||||
})
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
return rtr.navigateByUrl('/');
|
||||
})
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('{ hello }');
|
||||
|
||||
return fixture.componentInstance.onSomeAction();
|
||||
})
|
||||
.then((_) => {
|
||||
|
||||
// TODO(i): This should be rewritten to use NgZone#onStable or
|
||||
// something
|
||||
// similar basically the assertion needs to run when the world is
|
||||
// stable and we don't know when that is, only zones know.
|
||||
PromiseWrapper.resolve(null).then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('{ hello }');
|
||||
async.done();
|
||||
});
|
||||
})}));
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function registerSpecs() {
|
||||
specs['syncRoutesWithoutChildrenWithoutParams'] = syncRoutesWithoutChildrenWithoutParams;
|
||||
specs['syncRoutesWithoutChildrenWithParams'] = syncRoutesWithoutChildrenWithParams;
|
||||
@ -429,4 +487,5 @@ export function registerSpecs() {
|
||||
syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams;
|
||||
specs['syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams'] =
|
||||
syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams;
|
||||
specs['syncRoutesWithDynamicComponents'] = syncRoutesWithDynamicComponents;
|
||||
}
|
||||
|
@ -20,5 +20,7 @@ export function main() {
|
||||
describeWith('default routes', () => { describeWithout('params', itShouldRoute); });
|
||||
|
||||
});
|
||||
|
||||
describeWith('dynamic components', itShouldRoute);
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user