docs(router): add api docs
This commit is contained in:
parent
9f784dcc5a
commit
b98c9e74e1
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @module
|
||||
* @description
|
||||
* Alternative implementation of the router. Experimental.
|
||||
* Maps application URLs into application states, to support deep-linking and navigation.
|
||||
*/
|
||||
|
||||
export {Router, RouterOutletMap} from './src/router';
|
||||
|
@ -15,4 +15,24 @@ export {ROUTER_PROVIDERS} from './src/router_providers';
|
|||
import {RouterOutlet} from './src/directives/router_outlet';
|
||||
import {RouterLink} from './src/directives/router_link';
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* ```
|
||||
* import {Component} from '@angular/core';
|
||||
* import {ROUTER_DIRECTIVES, Routes} from '@angular/router-deprecated';
|
||||
*
|
||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
||||
* @RouteConfig([
|
||||
* {...},
|
||||
* ])
|
||||
* class AppCmp {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* bootstrap(AppCmp);
|
||||
* ```
|
||||
*/
|
||||
export const ROUTER_DIRECTIVES: any[] = /*@ts2dart_const*/[RouterOutlet, RouterLink];
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
/**
|
||||
* Name of the default outlet outlet.
|
||||
* @type {string}
|
||||
*/
|
||||
export const DEFAULT_OUTLET_NAME = "__DEFAULT";
|
|
@ -19,16 +19,49 @@ import {RouteSegment, UrlSegment, Tree} from '../segments';
|
|||
import {isString, isArray, isPresent} from '../facade/lang';
|
||||
import {ObservableWrapper} from '../facade/async';
|
||||
|
||||
/**
|
||||
* The RouterLink directive lets you link to specific parts of your app.
|
||||
*
|
||||
* Consider the following route configuration:
|
||||
|
||||
* ```
|
||||
* @Routes([
|
||||
* { path: '/user', component: UserCmp }
|
||||
* ]);
|
||||
* class MyComp {}
|
||||
* ```
|
||||
*
|
||||
* When linking to this `User` route, you can write:
|
||||
*
|
||||
* ```
|
||||
* <a [routerLink]="['/user']">link to user component</a>
|
||||
* ```
|
||||
*
|
||||
* RouterLink expects the value to be an array of path segments, followed by the params
|
||||
* for that level of routing. For instance `['/team', {teamId: 1}, 'user', {userId: 2}]`
|
||||
* means that we want to generate a link to `/team;teamId=1/user;userId=2`.
|
||||
*
|
||||
* The first segment name can be prepended with `/`, `./`, or `../`.
|
||||
* If the segment begins with `/`, the router will look up the route from the root of the app.
|
||||
* If the segment begins with `./`, or doesn't begin with a slash, the router will
|
||||
* instead look in the current component's children for the route.
|
||||
* And if the segment begins with `../`, the router will go up one segment in the url.
|
||||
*
|
||||
* See {@link Router.createUrlTree} for more information.
|
||||
*/
|
||||
@Directive({selector: '[routerLink]'})
|
||||
export class RouterLink implements OnDestroy {
|
||||
@Input() target: string;
|
||||
private _commands: any[] = [];
|
||||
private _subscription: any;
|
||||
|
||||
// the url displayed on the anchor element.
|
||||
@HostBinding() href: string;
|
||||
@HostBinding('class.router-link-active') isActive: boolean = false;
|
||||
|
||||
constructor(@Optional() private _routeSegment: RouteSegment, private _router: Router) {
|
||||
// because auxiliary links take existing primary and auxiliary routes into account,
|
||||
// we need to update the link whenever params or other routes change.
|
||||
this._subscription =
|
||||
ObservableWrapper.subscribe(_router.changes, (_) => { this._updateTargetUrlAndHref(); });
|
||||
}
|
||||
|
@ -48,6 +81,7 @@ export class RouterLink implements OnDestroy {
|
|||
|
||||
@HostListener("click")
|
||||
onClick(): boolean {
|
||||
// If no target, or if target is _self, prevent default browser behavior
|
||||
if (!isString(this.target) || this.target == '_self') {
|
||||
this._router.navigate(this._commands, this._routeSegment);
|
||||
return false;
|
||||
|
|
|
@ -13,6 +13,21 @@ import {RouterOutletMap} from '../router';
|
|||
import {DEFAULT_OUTLET_NAME} from '../constants';
|
||||
import {isPresent, isBlank} from '../facade/lang';
|
||||
|
||||
/**
|
||||
* A router outlet is a placeholder that Angular dynamically fills based on the application's route.
|
||||
*
|
||||
* ## Use
|
||||
*
|
||||
* ```
|
||||
* <router-outlet></router-outlet>
|
||||
* ```
|
||||
*
|
||||
* Outlets can be named.
|
||||
*
|
||||
* ```
|
||||
* <router-outlet name="right"></router-outlet>
|
||||
* ```
|
||||
*/
|
||||
@Directive({selector: 'router-outlet'})
|
||||
export class RouterOutlet {
|
||||
private _loaded: ComponentRef<any>;
|
||||
|
@ -28,10 +43,19 @@ export class RouterOutlet {
|
|||
this._loaded = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the loaded component.
|
||||
*/
|
||||
get loadedComponent(): Object { return isPresent(this._loaded) ? this._loaded.instance : null; }
|
||||
|
||||
/**
|
||||
* Returns true is the outlet is not empty.
|
||||
*/
|
||||
get isLoaded(): boolean { return isPresent(this._loaded); }
|
||||
|
||||
/**
|
||||
* Called by the Router to instantiate a new component.
|
||||
*/
|
||||
load(factory: ComponentFactory<any>, providers: ResolvedReflectiveProvider[],
|
||||
outletMap: RouterOutletMap): ComponentRef<any> {
|
||||
this.outletMap = outletMap;
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
import {RouteSegment, Tree, RouteTree} from './segments';
|
||||
|
||||
/**
|
||||
* Defines route lifecycle method `routerOnActivate`, which is called by the router at the end of a
|
||||
* successful route navigation.
|
||||
*
|
||||
* The `routerOnActivate` hook is called with the current and previous {@link RouteSegment}s of the
|
||||
* component and with the corresponding route trees.
|
||||
*/
|
||||
export interface OnActivate {
|
||||
routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: RouteTree,
|
||||
prevTree?: RouteTree): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines route lifecycle method `routerOnDeactivate`, which is called by the router before
|
||||
* destroying a component as part of a route change.
|
||||
*
|
||||
* The `routerOnDeactivate` hook is called with two {@link RouteTree}s, representing the current
|
||||
* and the future state of the application.
|
||||
*
|
||||
* `routerOnDeactivate` must return a promise. The route change will wait until the promise settles.
|
||||
*/
|
||||
export interface CanDeactivate {
|
||||
routerCanDeactivate(currTree?: RouteTree, futureTree?: RouteTree): Promise<boolean>;
|
||||
}
|
|
@ -3,6 +3,7 @@ import {isBlank, isPresent, isString, isStringMap} from './facade/lang';
|
|||
import {BaseException} from './facade/exceptions';
|
||||
import {ListWrapper} from './facade/collection';
|
||||
|
||||
// TODO: vsavkin: should reuse segments
|
||||
export function link(segment: RouteSegment, routeTree: RouteTree, urlTree: UrlTree, commands: any[]): UrlTree {
|
||||
if (commands.length === 0) return urlTree;
|
||||
|
||||
|
|
|
@ -3,6 +3,11 @@ library angular.alt_router.decorators;
|
|||
import 'metadata.dart';
|
||||
export 'metadata.dart';
|
||||
|
||||
/**
|
||||
* Defines routes for a given component.
|
||||
*
|
||||
* It takes an array of {@link RouteMetadata}s.
|
||||
*/
|
||||
class Routes extends RoutesMetadata {
|
||||
const Routes(List<RouteMetadata> routes): super(routes);
|
||||
}
|
|
@ -1,7 +1,19 @@
|
|||
import {RoutesMetadata, RouteMetadata} from "./metadata";
|
||||
import {makeDecorator} from '../core_private';
|
||||
|
||||
/**
|
||||
* Defines routes for a given component.
|
||||
*
|
||||
* It takes an array of {@link RouteMetadata}s.
|
||||
*/
|
||||
export interface RoutesFactory {
|
||||
(routes: RouteMetadata[]): any;
|
||||
new (routes: RouteMetadata[]): RoutesMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines routes for a given component.
|
||||
*
|
||||
* It takes an array of {@link RouteMetadata}s.
|
||||
*/
|
||||
export var Routes: RoutesFactory = <RoutesFactory>makeDecorator(RoutesMetadata);
|
||||
|
|
|
@ -1,12 +1,34 @@
|
|||
import {Type} from '@angular/core';
|
||||
import {stringify} from "../facade/lang";
|
||||
|
||||
/**
|
||||
* Information about a route.
|
||||
*
|
||||
* It has the following properties:
|
||||
* - `path` is a string that uses the route matcher DSL.
|
||||
* - `component` a component type.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* import {Routes} from '@angular/router';
|
||||
*
|
||||
* @Routes([
|
||||
* {path: '/home', component: HomeCmp}
|
||||
* ])
|
||||
* class MyApp {}
|
||||
* ```
|
||||
*
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export abstract class RouteMetadata {
|
||||
abstract get path(): string;
|
||||
abstract get component(): Type;
|
||||
}
|
||||
|
||||
/* @ts2dart_const */
|
||||
/**
|
||||
* See {@link RouteMetadata} for more information.
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class Route implements RouteMetadata {
|
||||
path: string;
|
||||
component: Type;
|
||||
|
@ -17,7 +39,12 @@ export class Route implements RouteMetadata {
|
|||
toString(): string { return `@Route(${this.path}, ${stringify(this.component)})`; }
|
||||
}
|
||||
|
||||
/* @ts2dart_const */
|
||||
/**
|
||||
* Defines routes for a given component.
|
||||
*
|
||||
* It takes an array of {@link RouteMetadata}s.
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class RoutesMetadata {
|
||||
constructor(public routes: RouteMetadata[]) {}
|
||||
toString(): string { return `@Routes(${this.routes})`; }
|
||||
|
|
|
@ -25,18 +25,30 @@ import {
|
|||
import {hasLifecycleHook} from './lifecycle_reflector';
|
||||
import {DEFAULT_OUTLET_NAME} from './constants';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class RouterOutletMap {
|
||||
/** @internal */
|
||||
_outlets: {[name: string]: RouterOutlet} = {};
|
||||
registerOutlet(name: string, outlet: RouterOutlet): void { this._outlets[name] = outlet; }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Router` is responsible for mapping URLs to components.
|
||||
*
|
||||
* You can see the state of the router by inspecting the read-only fields `router.urlTree`
|
||||
* and `router.routeTree`.
|
||||
*/
|
||||
export class Router {
|
||||
private _prevTree: RouteTree;
|
||||
private _urlTree: UrlTree;
|
||||
private _locationSubscription: any;
|
||||
private _changes: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(private _rootComponent: Object, private _rootComponentType: Type,
|
||||
private _componentResolver: ComponentResolver,
|
||||
private _urlSerializer: RouterUrlSerializer,
|
||||
|
@ -46,18 +58,94 @@ export class Router {
|
|||
this.navigateByUrl(this._location.path());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current url tree.
|
||||
*/
|
||||
get urlTree(): UrlTree { return this._urlTree; }
|
||||
|
||||
/**
|
||||
* Returns the current route tree.
|
||||
*/
|
||||
get routeTree(): RouteTree { return this._prevTree; }
|
||||
|
||||
/**
|
||||
* An observable or url changes from the router.
|
||||
*/
|
||||
get changes(): Observable<void> { return this._changes; }
|
||||
|
||||
/**
|
||||
* Navigate based on the provided url. This navigation is always absolute.
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
* ```
|
||||
* router.navigateByUrl("/team/33/user/11");
|
||||
* ```
|
||||
*/
|
||||
navigateByUrl(url: string): Promise<void> {
|
||||
return this._navigate(this._urlSerializer.parse(url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate based on the provided array of commands and a starting point.
|
||||
* If no segment is provided, the navigation is absolute.
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
* ```
|
||||
* router.navigate(['team', 33, 'team', '11], segment);
|
||||
* ```
|
||||
*/
|
||||
navigate(commands: any[], segment?: RouteSegment): Promise<void> {
|
||||
return this._navigate(this.createUrlTree(commands, segment));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
dispose(): void { ObservableWrapper.dispose(this._locationSubscription); }
|
||||
|
||||
/**
|
||||
* Applies an array of commands to the current url tree and creates
|
||||
* a new url tree.
|
||||
*
|
||||
* When given a segment, applies the given commands starting from the segment.
|
||||
* When not given a segment, applies the given command starting from the root.
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
* ```
|
||||
* // create /team/33/user/11
|
||||
* router.createUrlTree(['/team', 33, 'user', 11]);
|
||||
*
|
||||
* // create /team/33;expand=true/user/11
|
||||
* router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
|
||||
*
|
||||
* // you can collapse static fragments like this
|
||||
* router.createUrlTree(['/team/33/user', userId]);
|
||||
*
|
||||
* // assuming the current url is `/team/33/user/11` and the segment points to `user/11`
|
||||
*
|
||||
* // navigate to /team/33/user/11/details
|
||||
* router.createUrlTree(['details'], segment);
|
||||
*
|
||||
* // navigate to /team/33/user/22
|
||||
* router.createUrlTree(['../22'], segment);
|
||||
*
|
||||
* // navigate to /team/44/user/22
|
||||
* router.createUrlTree(['../../team/44/user/22'], segment);
|
||||
* ```
|
||||
*/
|
||||
createUrlTree(commands: any[], segment?: RouteSegment): UrlTree {
|
||||
let s = isPresent(segment) ? segment : this._prevTree.root;
|
||||
return link(s, this._prevTree, this.urlTree, commands);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a {@link UrlTree} into a string.
|
||||
*/
|
||||
serializeUrl(url: UrlTree): string { return this._urlSerializer.serialize(url); }
|
||||
|
||||
private _createInitialTree(): RouteTree {
|
||||
let root = new RouteSegment([new UrlSegment("", {}, null)], {}, DEFAULT_OUTLET_NAME,
|
||||
this._rootComponentType, null);
|
||||
|
@ -84,17 +172,6 @@ export class Router {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
createUrlTree(commands: any[], segment?: RouteSegment): UrlTree {
|
||||
let s = isPresent(segment) ? segment : this._prevTree.root;
|
||||
return link(s, this._prevTree, this.urlTree, commands);
|
||||
}
|
||||
|
||||
serializeUrl(url: UrlTree): string { return this._urlSerializer.serialize(url); }
|
||||
|
||||
get changes(): Observable<void> { return this._changes; }
|
||||
|
||||
get routeTree(): RouteTree { return this._prevTree; }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,28 @@ import {ROUTER_PROVIDERS_COMMON} from './router_providers_common';
|
|||
import {BrowserPlatformLocation} from '@angular/platform-browser';
|
||||
import {PlatformLocation} from '@angular/common';
|
||||
|
||||
/**
|
||||
* A list of {@link Provider}s. To use the router, you must add this to your application.
|
||||
*
|
||||
* ```
|
||||
* import {Component} from '@angular/core';
|
||||
* import {
|
||||
* ROUTER_DIRECTIVES,
|
||||
* ROUTER_PROVIDERS,
|
||||
* Routes
|
||||
* } from '@angular/router';
|
||||
*
|
||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
||||
* @Routes([
|
||||
* {...},
|
||||
* ])
|
||||
* class AppCmp {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* bootstrap(AppCmp, [ROUTER_PROVIDERS]);
|
||||
* ```
|
||||
*/
|
||||
export const ROUTER_PROVIDERS: any[] = /*@ts2dart_const*/[
|
||||
ROUTER_PROVIDERS_COMMON,
|
||||
/*@ts2dart_Provider*/ {provide: PlatformLocation, useClass: BrowserPlatformLocation},
|
||||
|
|
|
@ -5,6 +5,9 @@ import {RouterUrlSerializer, DefaultRouterUrlSerializer} from './router_url_seri
|
|||
import {ApplicationRef} from '@angular/core';
|
||||
import {BaseException} from '@angular/core';
|
||||
|
||||
/**
|
||||
* The Platform agnostic ROUTER PROVIDERS
|
||||
*/
|
||||
export const ROUTER_PROVIDERS_COMMON: any[] = /*@ts2dart_const*/[
|
||||
RouterOutletMap,
|
||||
/*@ts2dart_Provider*/ {provide: RouterUrlSerializer, useClass: DefaultRouterUrlSerializer},
|
||||
|
|
|
@ -2,11 +2,24 @@ import {UrlSegment, Tree, TreeNode, rootNode, UrlTree} from './segments';
|
|||
import {BaseException} from '@angular/core';
|
||||
import {isBlank, isPresent, RegExpWrapper} from './facade/lang';
|
||||
|
||||
/**
|
||||
* Defines a way to serialize/deserialize a url tree.
|
||||
*/
|
||||
export abstract class RouterUrlSerializer {
|
||||
/**
|
||||
* Parse a url into a {@Link UrlTree}
|
||||
*/
|
||||
abstract parse(url: string): UrlTree;
|
||||
|
||||
/**
|
||||
* Converts a {@Link UrlTree} into a url
|
||||
*/
|
||||
abstract serialize(tree: UrlTree): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A default implementation of the serialization.
|
||||
*/
|
||||
export class DefaultRouterUrlSerializer extends RouterUrlSerializer {
|
||||
parse(url: string): UrlTree {
|
||||
let root = new _UrlParser().parse(url);
|
||||
|
|
Loading…
Reference in New Issue