From 4fe17923cf49096470308cbafa3bf383f65a8d62 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Mon, 5 Oct 2015 16:37:31 -0700 Subject: [PATCH] docs(router): move examples into own file and add tests Closes #4620 --- .../ts/can_activate/can_activate_example.ts | 56 +++++++++++++ .../ts/can_activate/can_activate_spec.ts | 36 ++++++++ .../router/ts/can_activate/index.html | 24 ++++++ .../can_deactivate/can_deactivate_example.ts | 66 +++++++++++++++ .../ts/can_deactivate/can_deactivate_spec.ts | 52 ++++++++++++ .../router/ts/can_deactivate/index.html | 24 ++++++ .../examples/router/ts/on_activate/index.html | 24 ++++++ .../ts/on_activate/on_activate_example.ts | 46 ++++++++++ .../router/ts/on_activate/on_activate_spec.ts | 34 ++++++++ .../router/ts/on_deactivate/index.html | 24 ++++++ .../ts/on_deactivate/on_deactivate_example.ts | 61 ++++++++++++++ .../ts/on_deactivate/on_deactivate_spec.ts | 32 +++++++ .../examples/router/ts/reuse/index.html | 24 ++++++ .../examples/router/ts/reuse/reuse_example.ts | 56 +++++++++++++ .../examples/router/ts/reuse/reuse_spec.ts | 36 ++++++++ modules/angular2/src/router/interfaces.ts | 83 ++----------------- .../src/router/lifecycle_annotations.ts | 28 +++---- 17 files changed, 611 insertions(+), 95 deletions(-) create mode 100644 modules/angular2/examples/router/ts/can_activate/can_activate_example.ts create mode 100644 modules/angular2/examples/router/ts/can_activate/can_activate_spec.ts create mode 100644 modules/angular2/examples/router/ts/can_activate/index.html create mode 100644 modules/angular2/examples/router/ts/can_deactivate/can_deactivate_example.ts create mode 100644 modules/angular2/examples/router/ts/can_deactivate/can_deactivate_spec.ts create mode 100644 modules/angular2/examples/router/ts/can_deactivate/index.html create mode 100644 modules/angular2/examples/router/ts/on_activate/index.html create mode 100644 modules/angular2/examples/router/ts/on_activate/on_activate_example.ts create mode 100644 modules/angular2/examples/router/ts/on_activate/on_activate_spec.ts create mode 100644 modules/angular2/examples/router/ts/on_deactivate/index.html create mode 100644 modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts create mode 100644 modules/angular2/examples/router/ts/on_deactivate/on_deactivate_spec.ts create mode 100644 modules/angular2/examples/router/ts/reuse/index.html create mode 100644 modules/angular2/examples/router/ts/reuse/reuse_example.ts create mode 100644 modules/angular2/examples/router/ts/reuse/reuse_spec.ts diff --git a/modules/angular2/examples/router/ts/can_activate/can_activate_example.ts b/modules/angular2/examples/router/ts/can_activate/can_activate_example.ts new file mode 100644 index 0000000000..dbf8e2af70 --- /dev/null +++ b/modules/angular2/examples/router/ts/can_activate/can_activate_example.ts @@ -0,0 +1,56 @@ +import {bootstrap, bind, Component} from 'angular2/angular2'; +import { + CanActivate, + RouteConfig, + ComponentInstruction, + APP_BASE_HREF, + ROUTER_DIRECTIVES +} from 'angular2/router'; + +function checkIfWeHavePermission(instruction: ComponentInstruction) { + return instruction.params['id'] == '1'; +} + +// #docregion canActivate +@Component({selector: 'control-panel-cmp', template: `
Settings: ...
`}) +@CanActivate(checkIfWeHavePermission) +class ControlPanelCmp { +} +// #enddocregion + + +@Component({ + selector: 'home-cmp', + template: ` +

Welcome Home!

+
+ Edit User 1 | + Edit User 2 +
+ `, + directives: [ROUTER_DIRECTIVES] +}) +class HomeCmp { +} + + +@Component({ + selector: 'example-app', + template: ` +

My App

+ + `, + directives: [ROUTER_DIRECTIVES] +}) +@RouteConfig([ + {path: '/user-settings/:id', component: ControlPanelCmp, as: 'ControlPanelCmp'}, + {path: '/', component: HomeCmp, as: 'HomeCmp'} +]) +class AppCmp { +} + + +export function main() { + return bootstrap(AppCmp, + [bind(APP_BASE_HREF).toValue('/angular2/examples/router/ts/can_activate')]); +} diff --git a/modules/angular2/examples/router/ts/can_activate/can_activate_spec.ts b/modules/angular2/examples/router/ts/can_activate/can_activate_spec.ts new file mode 100644 index 0000000000..a06d7f690a --- /dev/null +++ b/modules/angular2/examples/router/ts/can_activate/can_activate_spec.ts @@ -0,0 +1,36 @@ +import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util'; +import {Promise} from 'angular2/src/core/facade/async'; + +function waitForElement(selector) { + var EC = (protractor).ExpectedConditions; + // Waits for the element with id 'abc' to be present on the dom. + browser.wait(EC.presenceOf($(selector)), 20000); +} + +describe('reuse example app', function() { + + afterEach(verifyNoBrowserErrors); + + var URL = 'angular2/examples/router/ts/can_activate/'; + + it('should navigate to user 1', function() { + browser.get(URL); + waitForElement('home-cmp'); + + element(by.css('#user-1-link')).click(); + waitForElement('control-panel-cmp'); + expect(browser.getCurrentUrl()).toMatch(/\/user-settings\/1$/); + + expect(element(by.css('control-panel-cmp')).getText()).toContain('Settings'); + }); + + it('should not navigate to user 2', function() { + browser.get(URL); + waitForElement('home-cmp'); + + element(by.css('#user-2-link')).click(); + waitForElement('home-cmp'); + + expect(element(by.css('home-cmp')).getText()).toContain('Welcome Home!'); + }); +}); diff --git a/modules/angular2/examples/router/ts/can_activate/index.html b/modules/angular2/examples/router/ts/can_activate/index.html new file mode 100644 index 0000000000..13c8bdab84 --- /dev/null +++ b/modules/angular2/examples/router/ts/can_activate/index.html @@ -0,0 +1,24 @@ + + + + Routing canActivate Lifecycle Example + + + + + + + + + + + Loading... + + + + diff --git a/modules/angular2/examples/router/ts/can_deactivate/can_deactivate_example.ts b/modules/angular2/examples/router/ts/can_deactivate/can_deactivate_example.ts new file mode 100644 index 0000000000..6b58edbdfe --- /dev/null +++ b/modules/angular2/examples/router/ts/can_deactivate/can_deactivate_example.ts @@ -0,0 +1,66 @@ +import {bind, bootstrap, Component} from 'angular2/angular2'; +import { + CanDeactivate, + RouteConfig, + RouteParams, + ComponentInstruction, + ROUTER_DIRECTIVES, + APP_BASE_HREF +} from 'angular2/router'; + +// #docregion canDeactivate +@Component({ + selector: 'note-cmp', + template: ` +
+

id: {{id}}

+ +
` +}) +class NoteCmp implements CanDeactivate { + id: string; + + constructor(params: RouteParams) { this.id = params.get('id'); } + + canDeactivate(next: ComponentInstruction, prev: ComponentInstruction) { + return confirm('Are you sure you want to leave?'); + } +} +// #enddocregion + + +@Component({ + selector: 'note-index-cmp', + template: ` +

Your Notes

+
+ Edit Note 1 | + Edit Note 2 +
+ `, + directives: [ROUTER_DIRECTIVES] +}) +class NoteIndexCmp { +} + + +@Component({ + selector: 'example-app', + template: ` +

My App

+ + `, + directives: [ROUTER_DIRECTIVES] +}) +@RouteConfig([ + {path: '/note/:id', component: NoteCmp, as: 'NoteCmp'}, + {path: '/', component: NoteIndexCmp, as: 'NoteIndexCmp'} +]) +class AppCmp { +} + + +export function main() { + return bootstrap(AppCmp, + [bind(APP_BASE_HREF).toValue('/angular2/examples/router/ts/can_deactivate')]); +} diff --git a/modules/angular2/examples/router/ts/can_deactivate/can_deactivate_spec.ts b/modules/angular2/examples/router/ts/can_deactivate/can_deactivate_spec.ts new file mode 100644 index 0000000000..a70533a47c --- /dev/null +++ b/modules/angular2/examples/router/ts/can_deactivate/can_deactivate_spec.ts @@ -0,0 +1,52 @@ +import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util'; +import {Promise} from 'angular2/src/core/facade/async'; + +function waitForElement(selector) { + var EC = (protractor).ExpectedConditions; + // Waits for the element with id 'abc' to be present on the dom. + browser.wait(EC.presenceOf($(selector)), 20000); +} + +function waitForAlert() { + var EC = (protractor).ExpectedConditions; + browser.wait(EC.alertIsPresent(), 1000); +} + +describe('can deactivate example app', function() { + + afterEach(verifyNoBrowserErrors); + + var URL = 'angular2/examples/router/ts/can_deactivate/'; + + it('should not navigate away when prompt is cancelled', function() { + browser.get(URL); + waitForElement('note-index-cmp'); + + element(by.css('#note-1-link')).click(); + waitForElement('note-cmp'); + + browser.navigate().back(); + waitForAlert(); + + browser.switchTo().alert().dismiss(); // Use to simulate cancel button + + expect(element(by.css('note-cmp')).getText()).toContain('id: 1'); + }); + + it('should navigate away when prompt is confirmed', function() { + browser.get(URL); + waitForElement('note-index-cmp'); + + element(by.css('#note-1-link')).click(); + waitForElement('note-cmp'); + + browser.navigate().back(); + waitForAlert(); + + browser.switchTo().alert().accept(); + + waitForElement('note-index-cmp'); + + expect(element(by.css('note-index-cmp')).getText()).toContain('Your Notes'); + }); +}); diff --git a/modules/angular2/examples/router/ts/can_deactivate/index.html b/modules/angular2/examples/router/ts/can_deactivate/index.html new file mode 100644 index 0000000000..a19917b671 --- /dev/null +++ b/modules/angular2/examples/router/ts/can_deactivate/index.html @@ -0,0 +1,24 @@ + + + + Routing canDeactivate Lifecycle Example + + + + + + + + + + + Loading... + + + + diff --git a/modules/angular2/examples/router/ts/on_activate/index.html b/modules/angular2/examples/router/ts/on_activate/index.html new file mode 100644 index 0000000000..12badf9ade --- /dev/null +++ b/modules/angular2/examples/router/ts/on_activate/index.html @@ -0,0 +1,24 @@ + + + + Routing Reuse Lifecycle Example + + + + + + + + + + + Loading... + + + + diff --git a/modules/angular2/examples/router/ts/on_activate/on_activate_example.ts b/modules/angular2/examples/router/ts/on_activate/on_activate_example.ts new file mode 100644 index 0000000000..5b19c960e1 --- /dev/null +++ b/modules/angular2/examples/router/ts/on_activate/on_activate_example.ts @@ -0,0 +1,46 @@ +import {Component, bind, bootstrap} from 'angular2/angular2'; +import { + OnActivate, + ComponentInstruction, + RouteConfig, + ROUTER_DIRECTIVES, + APP_BASE_HREF +} from 'angular2/router'; + + +// #docregion onActivate +@Component({selector: 'my-cmp', template: `
onActivate: {{log}}
`}) +class MyCmp implements OnActivate { + log: string = ''; + + onActivate(next: ComponentInstruction, prev: ComponentInstruction) { + this.log = `Finished navigating from "${prev ? prev.urlPath : 'null'}" to "${next.urlPath}"`; + } +} +// #enddocregion + + +@Component({ + selector: 'example-app', + template: ` +

My App

+ + + `, + directives: [ROUTER_DIRECTIVES] +}) +@RouteConfig([ + {path: '/', component: MyCmp, as: 'HomeCmp'}, + {path: '/:param', component: MyCmp, as: 'ParamCmp'} +]) +class AppCmp { +} + + +export function main() { + return bootstrap(AppCmp, + [bind(APP_BASE_HREF).toValue('/angular2/examples/router/ts/on_activate')]); +} diff --git a/modules/angular2/examples/router/ts/on_activate/on_activate_spec.ts b/modules/angular2/examples/router/ts/on_activate/on_activate_spec.ts new file mode 100644 index 0000000000..d37804c4ed --- /dev/null +++ b/modules/angular2/examples/router/ts/on_activate/on_activate_spec.ts @@ -0,0 +1,34 @@ +import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util'; +import {Promise} from 'angular2/src/core/facade/async'; + +function waitForElement(selector) { + var EC = (protractor).ExpectedConditions; + // Waits for the element with id 'abc' to be present on the dom. + browser.wait(EC.presenceOf($(selector)), 20000); +} + +describe('on activate example app', function() { + afterEach(verifyNoBrowserErrors); + + var URL = 'angular2/examples/router/ts/on_activate/'; + + it('should update the text when navigating between routes', function() { + browser.get(URL); + waitForElement('my-cmp'); + + expect(element(by.css('my-cmp')).getText()) + .toContain('onActivate: Finished navigating from "null" to ""'); + + element(by.css('#param-link')).click(); + waitForElement('my-cmp'); + + expect(element(by.css('my-cmp')).getText()) + .toContain('onActivate: Finished navigating from "" to "1"'); + + browser.navigate().back(); + waitForElement('my-cmp'); + + expect(element(by.css('my-cmp')).getText()) + .toContain('onActivate: Finished navigating from "1" to ""'); + }); +}); diff --git a/modules/angular2/examples/router/ts/on_deactivate/index.html b/modules/angular2/examples/router/ts/on_deactivate/index.html new file mode 100644 index 0000000000..13439d3d54 --- /dev/null +++ b/modules/angular2/examples/router/ts/on_deactivate/index.html @@ -0,0 +1,24 @@ + + + + Routing Reuse Lifecycle Example + + + + + + + + + + + Loading... + + + + diff --git a/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts b/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts new file mode 100644 index 0000000000..b4bc8e5502 --- /dev/null +++ b/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts @@ -0,0 +1,61 @@ +import {Component, Injectable, NgFor, bind, bootstrap} from 'angular2/angular2'; +import { + OnDeactivate, + ComponentInstruction, + RouteConfig, + ROUTER_DIRECTIVES, + APP_BASE_HREF +} from 'angular2/router'; + + +@Injectable() +class LogService { + logs: string[] = []; + + addLog(message: string): void { this.logs.push(message); } +} + + +// #docregion onDeactivate +@Component({selector: 'my-cmp', template: `
hello
`}) +class MyCmp implements OnDeactivate { + constructor(private logService: LogService) {} + + onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) { + this.logService.addLog( + `Navigating from "${prev ? prev.urlPath : 'null'}" to "${next.urlPath}"`); + } +} +// #enddocregion + + +@Component({ + selector: 'example-app', + template: ` +

My App

+ + +
+

Log:

+

{{ logItem }}

+
+ `, + directives: [ROUTER_DIRECTIVES, NgFor] +}) +@RouteConfig([ + {path: '/', component: MyCmp, as: 'HomeCmp'}, + {path: '/:param', component: MyCmp, as: 'ParamCmp'} +]) +class AppCmp { + constructor(public logService: LogService) {} +} + + +export function main() { + return bootstrap( + AppCmp, + [bind(APP_BASE_HREF).toValue('/angular2/examples/router/ts/on_deactivate'), LogService]); +} diff --git a/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_spec.ts b/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_spec.ts new file mode 100644 index 0000000000..c06a8ff228 --- /dev/null +++ b/modules/angular2/examples/router/ts/on_deactivate/on_deactivate_spec.ts @@ -0,0 +1,32 @@ +import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util'; +import {Promise} from 'angular2/src/core/facade/async'; + +function waitForElement(selector) { + var EC = (protractor).ExpectedConditions; + // Waits for the element with id 'abc' to be present on the dom. + browser.wait(EC.presenceOf($(selector)), 20000); +} + +describe('on activate example app', function() { + afterEach(verifyNoBrowserErrors); + + var URL = 'angular2/examples/router/ts/on_deactivate/'; + + it('should update the text when navigating between routes', function() { + browser.get(URL); + waitForElement('my-cmp'); + + expect(element(by.css('#log')).getText()).toEqual('Log:'); + + element(by.css('#param-link')).click(); + waitForElement('my-cmp'); + + expect(element(by.css('#log')).getText()).toEqual('Log:\nNavigating from "" to "1"'); + + browser.navigate().back(); + waitForElement('my-cmp'); + + expect(element(by.css('#log')).getText()) + .toEqual('Log:\nNavigating from "" to "1"\nNavigating from "1" to ""'); + }); +}); diff --git a/modules/angular2/examples/router/ts/reuse/index.html b/modules/angular2/examples/router/ts/reuse/index.html new file mode 100644 index 0000000000..6db5c421c6 --- /dev/null +++ b/modules/angular2/examples/router/ts/reuse/index.html @@ -0,0 +1,24 @@ + + + + Routing Reuse Lifecycle Example + + + + + + + + + + + Loading... + + + + diff --git a/modules/angular2/examples/router/ts/reuse/reuse_example.ts b/modules/angular2/examples/router/ts/reuse/reuse_example.ts new file mode 100644 index 0000000000..38c8d2feae --- /dev/null +++ b/modules/angular2/examples/router/ts/reuse/reuse_example.ts @@ -0,0 +1,56 @@ +import {bootstrap, Component, bind} from 'angular2/angular2'; +import { + CanActivate, + RouteConfig, + ComponentInstruction, + ROUTER_DIRECTIVES, + APP_BASE_HREF, + CanReuse, + RouteParams, + OnReuse +} from 'angular2/router'; + + +// #docregion reuseCmp +@Component({ + selector: 'my-cmp', + template: ` +
hello {{name}}!
+
message:
+ ` +}) +class MyCmp implements CanReuse, + OnReuse { + name: string; + constructor(params: RouteParams) { this.name = params.get('name') || 'NOBODY'; } + + canReuse(next: ComponentInstruction, prev: ComponentInstruction) { return true; } + + onReuse(next: ComponentInstruction, prev: ComponentInstruction) { + this.name = next.params['name']; + } +} +// #enddocregion + + +@Component({ + selector: 'example-app', + template: ` +

Say hi to...

+ Naomi | + Brad + + `, + directives: [ROUTER_DIRECTIVES] +}) +@RouteConfig([ + {path: '/', component: MyCmp, as: 'HomeCmp'}, + {path: '/:name', component: MyCmp, as: 'HomeCmp'} +]) +class AppCmp { +} + + +export function main() { + return bootstrap(AppCmp, [bind(APP_BASE_HREF).toValue('/angular2/examples/router/ts/reuse')]); +} diff --git a/modules/angular2/examples/router/ts/reuse/reuse_spec.ts b/modules/angular2/examples/router/ts/reuse/reuse_spec.ts new file mode 100644 index 0000000000..a004da063d --- /dev/null +++ b/modules/angular2/examples/router/ts/reuse/reuse_spec.ts @@ -0,0 +1,36 @@ +import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util'; +import {Promise} from 'angular2/src/core/facade/async'; + +function waitForElement(selector) { + var EC = (protractor).ExpectedConditions; + // Waits for the element with id 'abc' to be present on the dom. + browser.wait(EC.presenceOf($(selector)), 20000); +} + +describe('reuse example app', function() { + + afterEach(verifyNoBrowserErrors); + + var URL = 'angular2/examples/router/ts/reuse/'; + + it('should build a link which points to the detail page', function() { + browser.get(URL); + waitForElement('my-cmp'); + + element(by.css('#naomi-link')).click(); + waitForElement('my-cmp'); + expect(browser.getCurrentUrl()).toMatch(/\/naomi$/); + + // type something into input + element(by.css('#message')).sendKeys('long time no see!'); + + // navigate to Brad + element(by.css('#brad-link')).click(); + waitForElement('my-cmp'); + expect(browser.getCurrentUrl()).toMatch(/\/brad$/); + + // check that typed input is the same + expect(element(by.css('#message')).getAttribute('value')).toEqual('long time no see!'); + }); + +}); diff --git a/modules/angular2/src/router/interfaces.ts b/modules/angular2/src/router/interfaces.ts index 2fce4816a5..7879a240e1 100644 --- a/modules/angular2/src/router/interfaces.ts +++ b/modules/angular2/src/router/interfaces.ts @@ -22,20 +22,7 @@ var __ignore_me = global; * instantiate and activate child components. * * ### Example - * ``` - * import {Component} from 'angular2/angular2'; - * import {OnActivate, ComponentInstruction} from 'angular2/router'; - * - * @Component({ - * selector: 'my-cmp', - * template: '
hello!
' - * }) - * class MyCmp implements OnActivate { - * onActivate(next: ComponentInstruction, prev: ComponentInstruction) { - * this.log = 'Finished navigating from ' + prev.urlPath + ' to ' + next.urlPath; - * } - * } - * ``` + * {@example router/ts/on_activate/on_activate_example.ts region='onActivate'} */ export interface OnActivate { onActivate(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction): any; @@ -53,24 +40,7 @@ export interface OnActivate { * previous route or `null`. * * ### Example - * ``` - * import {Component} from 'angular2/angular2'; - * import {CanReuse, OnReuse, ComponentInstruction} from 'angular2/router'; - * - * @Component({ - * selector: 'my-cmp', - * template: '
hello!
' - * }) - * class MyCmp implements CanReuse, OnReuse { - * canReuse(next: ComponentInstruction, prev: ComponentInstruction) { - * return true; - * } - * - * onReuse(next: ComponentInstruction, prev: ComponentInstruction) { - * this.params = next.params; - * } - * } - * ``` + * {@example router/ts/reuse/reuse_example.ts region='reuseCmp'} */ export interface OnReuse { onReuse(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction): any; @@ -87,20 +57,7 @@ export interface OnReuse { * If `onDeactivate` returns a promise, the route change will wait until the promise settles. * * ### Example - * ``` - * import {Component} from 'angular2/angular2'; - * import {OnDeactivate, ComponentInstruction} from 'angular2/router'; - * - * @Component({ - * selector: 'my-cmp', - * template: '
hello!
' - * }) - * class MyCmp implements OnDeactivate { - * onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) { - * return this.doFadeAwayAnimation(); - * } - * } - * ``` + * {@example router/ts/on_deactivate/on_deactivate_example.ts region='onDeactivate'} */ export interface OnDeactivate { onDeactivate(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction): any; @@ -122,24 +79,7 @@ export interface OnDeactivate { * If `canReuse` throws or rejects, the navigation will be cancelled. * * ### Example - * ``` - * import {Component} from 'angular2/angular2'; - * import {CanReuse, OnReuse, ComponentInstruction} from 'angular2/router'; - * - * @Component({ - * selector: 'my-cmp', - * template: '
hello!
' - * }) - * class MyCmp implements CanReuse, OnReuse { - * canReuse(next: ComponentInstruction, prev: ComponentInstruction) { - * return next.params.id == prev.params.id; - * } - * - * onReuse(next: ComponentInstruction, prev: ComponentInstruction) { - * this.id = next.params.id; - * } - * } - * ``` + * {@example router/ts/reuse/reuse_example.ts region='reuseCmp'} */ export interface CanReuse { canReuse(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction): any; @@ -160,20 +100,7 @@ export interface CanReuse { * If `canDeactivate` throws or rejects, the navigation is also cancelled. * * ### Example - * ``` - * import {Component} from 'angular2/angular2'; - * import {CanDeactivate, ComponentInstruction} from 'angular2/router'; - * - * @Component({ - * selector: 'my-cmp', - * template: '
hello!
' - * }) - * class MyCmp implements CanDeactivate { - * canDeactivate(next: ComponentInstruction, prev: ComponentInstruction) { - * return askUserIfTheyAreSureTheyWantToQuit(); - * } - * } - * ``` + * {@example router/ts/can_deactivate/can_deactivate_example.ts region='canDeactivate'} */ export interface CanDeactivate { canDeactivate(nextInstruction: ComponentInstruction, prevInstruction: ComponentInstruction): any; diff --git a/modules/angular2/src/router/lifecycle_annotations.ts b/modules/angular2/src/router/lifecycle_annotations.ts index 7ee22c4aab..ff6c07b47f 100644 --- a/modules/angular2/src/router/lifecycle_annotations.ts +++ b/modules/angular2/src/router/lifecycle_annotations.ts @@ -20,13 +20,18 @@ export { * Defines route lifecycle hook `CanActivate`, which is called by the router to determine * if a component can be instantiated as part of a navigation. * - * The `CanActivate` 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`. - * + * + * + * The `CanActivate` 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`. + * + * ```typescript + * @CanActivate((next, prev) => boolean | Promise) + * ``` * * If `CanActivate` returns or resolves to `false`, the navigation is cancelled. * If `CanActivate` throws or rejects, the navigation is also cancelled. @@ -34,19 +39,8 @@ export { * instantiated, and the {@link OnActivate} hook of that component is called if implemented. * * ### Example - * ``` - * import {Component} from 'angular2/angular2'; - * import {CanActivate} from 'angular2/router'; * - * @Component({ - * selector: 'control-panel-cmp', - * template: '
Control Panel: ...
' - * }) - * @CanActivate(() => checkIfUserIsLoggedIn()) - * class ControlPanelCmp { - * // ... - * } - * ``` + * {@example router/ts/can_activate/can_activate_example.ts region='canActivate' } */ export var CanActivate: (hook: (next: ComponentInstruction, prev: ComponentInstruction) => Promise| boolean) =>