fix(router): respond to hashchange events

Previously if the URL changed in `HashLocation` mode, the router would not pick up the change.
This adds a listener in `HashLocationStrategy` for `hashchange` events to fix the problem.

Closes #5013
This commit is contained in:
Brian Ford 2015-10-30 08:48:47 -07:00
parent cb2b690471
commit 53bddec1d2
6 changed files with 95 additions and 0 deletions

View File

@ -63,6 +63,7 @@ export class PathLocationStrategy extends LocationStrategy {
onPopState(fn: EventListener): void { onPopState(fn: EventListener): void {
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false); DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
DOM.getGlobalEventTarget('window').addEventListener('hashchange', fn, false);
} }
getBaseHref(): string { return this._baseHref; } getBaseHref(): string { return this._baseHref; }

View File

@ -0,0 +1,3 @@
library playground.e2e_test.hash_location_spec;
main() {}

View File

@ -0,0 +1,29 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
import {Promise} from 'angular2/src/core/facade/async';
function waitForElement(selector) {
var EC = (<any>protractor).ExpectedConditions;
// Waits for the element with id 'abc' to be present on the dom.
browser.wait(EC.presenceOf($(selector)), 20000);
}
describe('hash routing example app', function() {
afterEach(verifyNoBrowserErrors);
var URL = 'playground/src/hash_routing/index.html';
it('should navigate between routes', function() {
browser.get(URL + '#/bye');
waitForElement('goodbye-cmp');
element(by.css('#hello-link')).click();
waitForElement('hello-cmp');
expect(element(by.css('hello-cmp')).getText()).toContain('hello');
browser.navigate().back();
waitForElement('goodbye-cmp');
expect(element(by.css('goodbye-cmp')).getText()).toContain('goodbye');
});
});

View File

@ -0,0 +1,12 @@
<!doctype html>
<html>
<title>Routing Example</title>
<base href="/playground/src/hash_routing/">
<body>
<example-app>
Loading...
</example-app>
$SCRIPTS$
</body>
</html>

View File

@ -0,0 +1,49 @@
import {Component, provide} from 'angular2/angular2';
import {bootstrap} from 'angular2/bootstrap';
import {
RouteConfig,
Route,
ROUTER_PROVIDERS,
ROUTER_DIRECTIVES,
HashLocationStrategy,
LocationStrategy
} from 'angular2/router';
import {reflector} from 'angular2/src/core/reflection/reflection';
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
@Component({selector: 'hello-cmp', template: `hello`})
class HelloCmp {
}
@Component({selector: 'goodbye-cmp', template: `goodbye`})
class GoodByeCmp {
}
@Component({
selector: 'example-app',
template: `
<h1>My App</h1>
<nav>
<a href="#/" id="hello-link">Navigate via href</a> |
<a [router-link]="['/GoodbyeCmp']" id="goodbye-link">Navigate with Link DSL</a>
</nav>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
new Route({path: '/', component: HelloCmp, name: 'HelloCmp'}),
new Route({path: '/bye', component: GoodByeCmp, name: 'GoodbyeCmp'})
])
class AppCmp {
}
export function main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrap(AppCmp,
[ROUTER_PROVIDERS, provide(LocationStrategy, {useClass: HashLocationStrategy})]);
}

View File

@ -43,6 +43,7 @@ const kServedPaths = [
'playground/src/person_management', 'playground/src/person_management',
'playground/src/order_management', 'playground/src/order_management',
'playground/src/gestures', 'playground/src/gestures',
'playground/src/hash_routing',
'playground/src/hello_world', 'playground/src/hello_world',
'playground/src/http', 'playground/src/http',
'playground/src/jsonp', 'playground/src/jsonp',