Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 99 additions & 9 deletions modules/angular2/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,101 @@ import {Location} from './src/router/location';
import {bind, OpaqueToken, Binding} from './core';
import {CONST_EXPR, Type} from './src/core/facade/lang';

/**
* Token used to bind the component with the top-level {@link RouteConfig}s for the
* application.
*
* You can use the {@link routerBindings} function in your {@link bootstrap} bindings to
* simplify setting up these bindings.
*
* ## Example
*
* ```
* import {Component, View} from 'angular2/angular2';
* import {
* ROUTER_DIRECTIVES,
* ROUTER_BINDINGS,
* ROUTER_PRIMARY_COMPONENT,
* RouteConfig
* } from 'angular2/router';
*
* @Component({...})
* @View({directives: [ROUTER_DIRECTIVES]})
* @RouteConfig([
* {...},
* ])
* class AppCmp {
* // ...
* }
*
* bootstrap(AppCmp, [
* ROUTER_BINDINGS,
* bind(ROUTER_PRIMARY_COMPONENT).toValue(AppCmp)
* ]);
* ```
*/
export const ROUTER_PRIMARY_COMPONENT: OpaqueToken =
CONST_EXPR(new OpaqueToken('RouterPrimaryComponent'));

export const ROUTER_DIRECTIVES: any[] = CONST_EXPR([RouterOutlet, RouterLink]);

/**
* A list of {@link Binding}. To use the router, you must add this to your application.
* A list of directives. To use the router directives like {@link RouterOutlet} and
* {@link RouterLink}, add this to your `directives` array in the {@link View} decorator of your
* component.
*
* ## Example
*
* ```typescript
* ```
* import {Component, View} from 'angular2/angular2';
* import {ROUTER_DIRECTIVES, routerBindings, RouteConfig} from 'angular2/router';
*
* @Component({...})
* @View({directives: [ROUTER_DIRECTIVES]})
* @RouteConfig([
* new Route(...),
* {...},
* ])
* class AppCmp {
* constructor(router: Router, location: Location) {
* // ...
* }
*
* }
*
*
* bootstrap(AppCmp, [routerBindings(AppCmp)]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here routerBindings -> ROUTER_BINDINGS ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah never mind, seen later that routerBindings is a helper function. I find it rather confusing at first tho

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I think we should only export the helper TBH.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there use cases (maybe in tests) where we are really just interested in ROUTER_BINDINGS?

* ```
*/
export const ROUTER_DIRECTIVES: any[] = CONST_EXPR([RouterOutlet, RouterLink]);

/**
* A list of {@link Binding}s. To use the router, you must add this to your application.
*
* Note that you also need to bind to {@link ROUTER_PRIMARY_COMPONENT}.
*
* You can use the {@link routerBindings} function in your {@link bootstrap} bindings to
* simplify setting up these bindings.
*
* ## Example
*
* ```
* import {Component, View} from 'angular2/angular2';
* import {
* ROUTER_DIRECTIVES,
* ROUTER_BINDINGS,
* ROUTER_PRIMARY_COMPONENT,
* RouteConfig
* } from 'angular2/router';
*
* @Component({...})
* @View({directives: [ROUTER_DIRECTIVES]})
* @RouteConfig([
* {...},
* ])
* class AppCmp {
* // ...
* }
*
* bootstrap(AppCmp, [
* ROUTER_BINDINGS,
* bind(ROUTER_PRIMARY_COMPONENT).toValue(AppCmp)
* ]);
* ```
*/
export const ROUTER_BINDINGS: any[] = CONST_EXPR([
RouteRegistry,
CONST_EXPR(new Binding(LocationStrategy, {toClass: PathLocationStrategy})),
Expand All @@ -75,6 +143,28 @@ function routerFactory(registry, location, primaryComponent) {
return new RootRouter(registry, location, primaryComponent);
}

/**
* A list of {@link Binding}s. To use the router, you must add these bindings to
* your application.
*
* ## Example
*
* ```
* import {Component, View} from 'angular2/angular2';
* import {ROUTER_DIRECTIVES, routerBindings, RouteConfig} from 'angular2/router';
*
* @Component({...})
* @View({directives: [ROUTER_DIRECTIVES]})
* @RouteConfig([
* {...},
* ])
* class AppCmp {
* // ...
* }
*
* bootstrap(AppCmp, [routerBindings(AppCmp)]);
* ```
*/
export function routerBindings(primaryComponent: Type): Array<any> {
return [ROUTER_BINDINGS, bind(ROUTER_PRIMARY_COMPONENT).toValue(primaryComponent)];
}
39 changes: 39 additions & 0 deletions modules/angular2/src/router/hash_location_strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,45 @@ import {Injectable} from 'angular2/src/core/di';
import {LocationStrategy} from './location_strategy';
import {EventListener, History, Location} from 'angular2/src/core/facade/browser';

/**
* `HashLocationStrategy` is a {@link LocationStrategy} used to configure the
* {@link Location} service to represent its state in the
* [hash fragment](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax)
* of the browser's URL.
*
* `HashLocationStrategy` is the default binding for {@link LocationStrategy}
* provided in {@link routerBindings} and {@link ROUTER_BINDINGS}.
*
* For instance, if you call `location.go('/foo')`, the browser's URL will become
* `example.com#/foo`.
*
* ## Example
*
* ```
* import {Component, View} from 'angular2/angular2';
* import {
* ROUTER_DIRECTIVES,
* routerBindings,
* RouteConfig,
* Location
* } from 'angular2/router';
*
* @Component({...})
* @View({directives: [ROUTER_DIRECTIVES]})
* @RouteConfig([
* {...},
* ])
* class AppCmp {
* constructor(location: Location) {
* location.go('/foo');
* }
* }
*
* bootstrap(AppCmp, [
* routerBindings(AppCmp) // includes binding to HashLocationStrategy
* ]);
* ```
*/
@Injectable()
export class HashLocationStrategy extends LocationStrategy {
private _location: Location;
Expand Down
115 changes: 83 additions & 32 deletions modules/angular2/src/router/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,76 +8,102 @@ var __ignore_me = global;


/**
* Defines route lifecycle method [onActivate], which is called by the router at the end of a
* Defines route lifecycle method `onActivate`, which is called by the router at the end of a
* successful route navigation.
*
* For a single component's navigation, only one of either [onActivate] or [onReuse] will be called,
* depending on the result of [canReuse].
* For a single component's navigation, only one of either {@link OnActivate} or {@link OnReuse}
* will be called depending on the result of {@link CanReuse}.
*
* The `onActivate` hook is called with two {@link ComponentInstruction}s as parameters, the first
* representing the current route being navigated to, and the second parameter representing the
* previous route or `null`.
*
* If `onActivate` returns a promise, the route change will wait until the promise settles to
* instantiate and activate child components.
*
* ## Example
* ```
* @Directive({
* import {Component, View} from 'angular2/angular2';
* import {OnActivate, ComponentInstruction} from 'angular2/router';
*
* @Component({
* selector: 'my-cmp'
* })
* @View({
* template: '<div>hello!</div>'
* })
* class MyCmp implements OnActivate {
* onActivate(next, prev) {
* onActivate(next: ComponentInstruction, prev: ComponentInstruction) {
* this.log = 'Finished navigating from ' + prev.urlPath + ' to ' + next.urlPath;
* }
* }
* ```
* ```
*/
export interface OnActivate {
onActivate(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction): any;
}

/**
* Defines route lifecycle method [onReuse], which is called by the router at the end of a
* successful route navigation when [canReuse] is implemented and returns or resolves to true.
* Defines route lifecycle method `onReuse`, which is called by the router at the end of a
* successful route navigation when {@link CanReuse} is implemented and returns or resolves to true.
*
* For a single component's navigation, only one of either {@link OnActivate} or {@link OnReuse}
* will be called, depending on the result of {@link CanReuse}.
*
* For a single component's navigation, only one of either [onActivate] or [onReuse] will be called,
* depending on the result of [canReuse].
* The `onReuse` hook is called with two {@link ComponentInstruction}s as parameters, the first
* representing the current route being navigated to, and the second parameter representing the
* previous route or `null`.
*
* ## Example
* ```
* @Directive({
* import {Component, View} from 'angular2/angular2';
* import {CanReuse, OnReuse, ComponentInstruction} from 'angular2/router';
*
* @Component({
* selector: 'my-cmp'
* })
* @View({
* template: '<div>hello!</div>'
* })
* class MyCmp implements CanReuse, OnReuse {
* canReuse() {
* canReuse(next: ComponentInstruction, prev: ComponentInstruction) {
* return true;
* }
*
* onReuse(next, prev) {
* onReuse(next: ComponentInstruction, prev: ComponentInstruction) {
* this.params = next.params;
* }
* }
* ```
* ```
*/
export interface OnReuse {
onReuse(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction): any;
}

/**
* Defines route lifecycle method [onDeactivate], which is called by the router before destroying
* Defines route lifecycle method `onDeactivate`, which is called by the router before destroying
* a component as part of a route change.
*
* The `onDeactivate` hook is called with two {@link ComponentInstruction}s as parameters, the first
* representing the current route being navigated to, and the second parameter representing the
* previous route.
*
* If `onDeactivate` returns a promise, the route change will wait until the promise settles.
*
* ## Example
* ```
* @Directive({
* import {Component, View} from 'angular2/angular2';
* import {OnDeactivate, ComponentInstruction} from 'angular2/router';
*
* @Component({
* selector: 'my-cmp'
* })
* class MyCmp implements CanReuse, OnReuse {
* canReuse() {
* return true;
* }
*
* onReuse(next, prev) {
* this.params = next.params;
* @View({
* template: '<div>hello!</div>'
* })
* class MyCmp implements OnDeactivate {
* onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
* return this.doFadeAwayAnimation();
* }
* }
* ```
Expand All @@ -87,24 +113,37 @@ export interface OnDeactivate {
}

/**
* Defines route lifecycle method [canReuse], which is called by the router to determine whether a
* Defines route lifecycle method `canReuse`, which is called by the router to determine whether a
* component should be reused across routes, or whether to destroy and instantiate a new component.
*
* If `canReuse` returns or resolves to `true`, the component instance will be reused.
* The `canReuse` hook is called with two {@link ComponentInstruction}s as parameters, the first
* representing the current route being navigated to, and the second parameter representing the
* previous route.
*
* If `canReuse` returns or resolves to `true`, the component instance will be reused and the
* {@link OnDeactivate} hook will be run. If `canReuse` returns or resolves to `false`, a new
* component will be instantiated, and the existing component will be deactivated and removed as
* part of the navigation.
*
* If `canReuse` throws or rejects, the navigation will be cancelled.
*
* ## Example
* ```
* @Directive({
* import {Component, View} from 'angular2/angular2';
* import {CanReuse, OnReuse, ComponentInstruction} from 'angular2/router';
*
* @Component({
* selector: 'my-cmp'
* })
* @View({
* template: '<div>hello!</div>'
* })
* class MyCmp implements CanReuse, OnReuse {
* canReuse(next, prev) {
* canReuse(next: ComponentInstruction, prev: ComponentInstruction) {
* return next.params.id == prev.params.id;
* }
*
* onReuse(next, prev) {
* onReuse(next: ComponentInstruction, prev: ComponentInstruction) {
* this.id = next.params.id;
* }
* }
Expand All @@ -115,20 +154,32 @@ export interface CanReuse {
}

/**
* Defines route lifecycle method [canDeactivate], which is called by the router to determine
* Defines route lifecycle method `canDeactivate`, which is called by the router to determine
* if a component can be removed as part of a navigation.
*
* If `canDeactivate` returns or resolves to `false`, the navigation is cancelled.
* The `canDeactivate` hook is called with two {@link ComponentInstruction}s as parameters, the
* first representing the current route being navigated to, and the second parameter
* representing the previous route.
*
* If `canDeactivate` returns or resolves to `false`, the navigation is cancelled. If it returns or
* resolves to `true`, then the navigation continues, and the component will be deactivated
* (the {@link OnDeactivate} hook will be run) and removed.
*
* If `canDeactivate` throws or rejects, the navigation is also cancelled.
*
* ## Example
* ```
* @Directive({
* import {Component, View} from 'angular2/angular2';
* import {CanDeactivate, ComponentInstruction} from 'angular2/router';
*
* @Component({
* selector: 'my-cmp'
* })
* @View({
* template: '<div>hello!</div>'
* })
* class MyCmp implements CanDeactivate {
* canDeactivate(next, prev) {
* canDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
* return askUserIfTheyAreSureTheyWantToQuit();
* }
* }
Expand Down
Loading