Routing in Eleven Dimensions
With Component Router
Brian Ford�Slides: goo.gl/n38EDf
Angular Connect, London, October 2015
One Question
Angular Connect, London, October 2015
Is Angular Actually Recovered Extraterrestrial Technology?
Angular Connect, London, October 2015
Consider an Email App
Angular Connect, London, October 2015
URGENT: this flag is orange
Did you get that thing I sent you?
consectetur adipiscing elit sed
Capitalism happened again
exercitationem ullam corporis suscipit laboriosam
At vero eos et accusamus et�iusto odio dignissimos
Your flight from ABC to DEF
Angular Connect, London, October 2015
Don't forget important things like your laptop
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Routing Basics
Angular Connect, London, October 2015
URGENT: this flag is orange
Did you get that thing I sent you?
consectetur adipiscing elit sed
Capitalism happened again
exercitationem ullam corporis suscipit laboriosam
At vero eos et accusamus et�iusto odio dignissimos
Your flight from ABC to DEF
Angular Connect, London, October 2015
URGENT: this flag is orange
Did you get that thing I sent you?
consectetur adipiscing elit sed
Capitalism happened again
exercitationem ullam corporis suscipit laboriosam
At vero eos et accusamus et�iusto odio dignissimos
Your flight from ABC to DEF
Angular Connect, London, October 2015
URGENT: this flag is orange
Did you get that thing I sent you?
consectetur adipiscing elit sed
Capitalism happened again
exercitationem ullam corporis suscipit laboriosam
At vero eos et accusamus et�iusto odio dignissimos
Your flight from ABC to DEF
<router-outlet>
Angular Connect, London, October 2015
AppCmp
outlet
IndexCmp
DetailCmp
SearchCmp
example.com/
example.com/email/1234
example.com/search?query=github
Angular Connect, London, October 2015
Route Config– URL to component
IndexCmp
DetailCmp
SearchCmp
example.com/
example.com/email/1234
example.com/search?query=github
Angular Connect, London, October 2015
Route Config– URL to component
@Component( … )�@RouteConfig([� { path: '/', component: IndexCmp },� { path: '/email/:id', component: EmailCmp },� { path: '/search', component: SearchCmp }�])�class AppCmp {}
Angular Connect, London, October 2015
Route Config– the path property
The "path" part of the route config:��– '/' – matches '/' or '' (empty string)�– '/search' – matches the URL '/search'�– '/:id' – matches any string, provides a RouteParam named id
More on this DSL later...
Angular Connect, London, October 2015
Route Params
@Component( … )�@RouteConfig([� { path: '/', component: IndexCmp },� { path: '/email/:id', component: EmailCmp },� { path: '/search', component: SearchCmp }�])�class AppCmp {}
Angular Connect, London, October 2015
Route Params
@Component( … )�class EmailCmp {� constructor(params: RouteParams) {� this.id = params.get('id');� }�}
Angular Connect, London, October 2015
URGENT: this flag is orange
Did you get that thing I sent you?
consectetur adipiscing elit sed
Capitalism happened again
exercitationem ullam corporis suscipit laboriosam
At vero eos et accusamus et�iusto odio dignissimos
Your flight from ABC to DEF
example.com/
Angular Connect, London, October 2015
Don't forget important things like your laptop
example.com/email/1234
Angular Connect, London, October 2015
example.com/search?query=github%20angular
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Creating Links
Angular Connect, London, October 2015
Creating Links– Naming Routes
@Component( … )�@RouteConfig([� { path: '/', component: IndexCmp, as: 'Index' },� { path: '/email/:id', component: EmailCmp, as: 'Email' },� { path: '/search', component: SearchCmp, as: 'Search' }�])�class AppCmp {}
Angular Connect, London, October 2015
Creating Links
@Component({� selector: 'app-cmp'� template: `<router-outlet></router-outlet>`,� directives: ROUTER_DIRECTIVES�})�@RouteConfig([� { path: '/', component: IndexCmp, as: 'Index' },� { path: '/email/:id', component: EmailCmp, as: 'Email' },� { path: '/search', component: SearchCmp, as: 'Search' }�])�class AppCmp {}
Angular Connect, London, October 2015
Creating Links
@Component({� selector: 'app-cmp'� template: `<a [router-link]="['/Index']">Index</a>� <a [router-link]="['/Search']">Search</a>� <router-outlet></router-outlet>`,� directives: ROUTER_DIRECTIVES�})�@RouteConfig([� { path: '/', component: IndexCmp, as: 'Index' },� { path: '/email/:id', component: EmailCmp, as: 'Email' },� { path: '/search', component: SearchCmp, as: 'Search' }�])�class AppCmp {}
Angular Connect, London, October 2015
Link DSL
<a [router-link]=" [ '/Index' ] ">Email Index</a>
Absolute
Route name
Data binding
JavaScript Array
Angular Connect, London, October 2015
Link DSL
AppCmp's @RouteConfig� { path: '/', component: HomeCmp, as: 'Index' }
<a [router-link]="[ '/Index' ]">home</a>
<a href="/">home</a>
Angular Connect, London, October 2015
Link DSL mirrors the URL, but uses route names and params instead of URL segments
Angular Connect, London, October 2015
Link DSL– Params
@Component( … )�@RouteConfig([� { path: '/', component: IndexCmp, as: 'Index' },� { path: '/email/:id', component: EmailCmp, as: 'Email' },� { path: '/search', component: SearchCmp, as: 'Search' }�])�class AppCmp {}
Angular Connect, London, October 2015
Link DSL– Params
@Component({� selector: 'index-cmp'� template: `�<ul>� <li *ng-for="#email of emails">� <a [router-link]="[ '/Email', { id: email.id } ]">{{ email.subject }}</a>� </li>�</ul>`,� directives: ROUTER_DIRECTIVES�})�class IndexCmp {}
Angular Connect, London, October 2015
Link DSL– Params
<a [router-link]=" [ '/Email' , { id: 123 } ] ">
Route name
JavaScript Array
JavaScript Object
Route params
Angular Connect, London, October 2015
Link DSL– Params
� { path: '/email/:id', component: EmailCmp, as: 'Email' }
<a [router-link]="[ '/Email', { id: 123 } ]">Hello</a>
<a href="/email/123">Hello</a>
AppCmp's @RouteConfig
Angular Connect, London, October 2015
Link DSL is robust, survives refactors better than URLs
Angular Connect, London, October 2015
Fundamental Components of Routing
Angular Connect, London, October 2015
Child Routes
Angular Connect, London, October 2015
Here are those files
Hi friend! I know how much you like files, so I sent some to you in this email.
Dave to me
Lorem ipsum dolor sit amet, sit atqui imperdiet moderatius in.
Quo regione gloriatur scripserit ne, eos ei dicunt fastidii expetendis, eos ut legendos consetetur. Pri eu consulatu gubergren, euismod praesent vix at, esse delenit liberavisse usu id.
Purto volumus omnesque nec ei. Nec affert oblique nonumes ex.At quo maiestatis consectetuer, nam quidam iisque et. Autem affert saperet eum ut, id mel percipit facilisi. Quot suscipiantur deterruisset id eos. Ex quo mazim omnes imperdiet.Ad eos prima aliquip sententiae, ancillae accusata ius id, his ei prodesset elaboraret interpretaris.
Ex graeco accommodare mel, nam reque argumentum eu. Ea elitr mnesarchum deterruisset qui.
At augue persius gloriatur per, falli laudem tamquam pri ut. Sea mazim harum intellegat ea, usu ea dico labore quidam. Mediocrem ullamcorper est ea.
Dave to me
Angular Connect, London, October 2015
Here are those files
Hi friend! I know how much you like files, so I sent some to you in this email.
Dave to me
some_file.js��last modified: Fri 3:21pm�size: 456 kB
Angular Connect, London, October 2015
Here are those files
Hi friend! I know how much you like files, so I sent some to you in this email.
Dave to me
some_file.js��last modified: Fri 3:21pm�size: 456 kB
<router-outlet>
Angular Connect, London, October 2015
Child Routes allow you encapsulate nested routes
Angular Connect, London, October 2015
Child Routes– EmailCmp Config
@Component( … )�@RouteConfig([� { path: '/', component: ThreadCmp, as: 'Thread' },� { path: '/file/:id', component: FileCmp, as: 'File' }�])�class EmailCmp {}
Angular Connect, London, October 2015
Child Routes– EmailCmp Config
@Component({� selector: 'index-cmp'� template: `<h2>{{subject}}</h2>� <p>{{body}}</p>� <router-outlet><router-outlet>`,� directives: ROUTER_DIRECTIVES�})�@RouteConfig( … )�class EmailCmp {}
Angular Connect, London, October 2015
Child Routes– AppCmp Config
@Component( … )�@RouteConfig([� { path: '/', component: IndexCmp, as: 'Index' },� { path: '/email/:id/...', component: EmailCmp, as: 'Email' },� { path: '/search', component: SearchCmp, as: 'Search' }�])�class AppCmp {}
Angular Connect, London, October 2015
Child Routes– Link
<a [router-link]=" [ '/Email' , { id: 123 }� 'Thread' ] ">
Route name
Route params
Child route name
Angular Connect, London, October 2015
Child Routes– Link
� { path: '/email/:id/...', component: EmailCmp, as: 'Email' }
<a [router-link]="[ '/Email', { id: 123 }, 'Thread' ]">Hello</a>
<a href="/email/123">Hello</a>
AppCmp's @RouteConfig
Angular Connect, London, October 2015
Child Routes– Link
� { path: '/', component: ThreadCmp, as: 'Thread' }
<a [router-link]="[ '/Email', { id: 123 }, 'Thread' ]">Hello</a>
<a href="/email/123">Hello</a>
EmailCmp's @RouteConfig
Angular Connect, London, October 2015
Child Routes– Link
<a [router-link]=" [ '/Email' , { id: 123 }� 'File', { id: 'xyz' } ] ">
Route name
Route params
Child route name
Child route params
Angular Connect, London, October 2015
Child Routes– Link
� { path: '/email/:id/...', component: EmailCmp, as: 'Email' }
<a [router-link]="[ '/Email', { id: 123 },� 'File', { id: 'xyz' } ]">Hello</a>
<a href="/email/123/...">Hello</a>
AppCmp's @RouteConfig
Angular Connect, London, October 2015
Child Routes– Link
� { path: '/file/:id', component: ThreadCmp, as: 'File' }
<a href="/email/123/file/xyz">Hello</a>
<a [router-link]="[ '/Email', { id: 123 },� 'File', { id: 'xyz' } ]">Hello</a>
EmailCmp's @RouteConfig
Angular Connect, London, October 2015
Child Routes have their own params– no need to worry about collisions
Angular Connect, London, October 2015
Child Routes– Relative Links
<a [router-link]=" [ '/Email' , { id: 123 }� 'File', { id: 'xyz' } ] ">
Route name
Route params
Child route name
Child route params
Absolute
Angular Connect, London, October 2015
Child Routes– Relative Links
<a [router-link]=" [ './File', { id: 'xyz' } ] ">
Child route name
Child route params
Relative Child
Angular Connect, London, October 2015
Eleven-dimensional Routing�(with auxiliary routes)
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Auxiliary Routes allow for multiple independent routes
Angular Connect, London, October 2015
Auxiliary Route– Outlets
Each component has one primary and zero or more auxiliary outlets.
Auxiliary outlets within the same component must have a unique name.
<router-outlet>
<router-outlet name="draft">
AppCmp
Angular Connect, London, October 2015
Auxiliary Routes– Named Outlet
@Component({� selector: 'app-cmp'� template: `<a [router-link]="['/Index']">Index</a>� <a [router-link]="['/Search']">Search</a>� <router-outlet></router-outlet>� <router-outlet name="draft"></router-outlet>`,� directives: ROUTER_DIRECTIVES�})�@RouteConfig( … )�class AppCmp {}
Angular Connect, London, October 2015
Auxiliary Routes– Config
@Component( … )�@RouteConfig([� { path: '/', component: IndexCmp, as: 'Index' },� { path: '/email/:id', component: EmailCmp, as: 'Email' },� { path: '/search', component: SearchCmp, as: 'Search' },� { aux: '/draft', component: DraftCmp, as: 'Draft' }�])�class AppCmp {}
Angular Connect, London, October 2015
awks
like "awkward"
"aux" is pronounced
Angular Connect, London, October 2015
Auxiliary Routes– Link
@Component({� selector: 'app-cmp'� template: `<a [router-link]="['/Index']">Index</a>� <a [router-link]="['/Search']">Search</a>� <router-outlet></router-outlet>� <router-outlet name="draft"></router-outlet>� <a [router-link]="['/', ['Draft'] ]">New Email</a>`,� directives: ROUTER_DIRECTIVES�})�@RouteConfig( … )�class AppCmp {}
Angular Connect, London, October 2015
Auxiliary Routes– Link
<a [router-link]=" [ '/' , [ 'Draft' ] ]">
JavaScript Array
Aux Route Name
Absolute
Angular Connect, London, October 2015
Auxiliary Routes– URL
URL segments represent hierarchy:
/parent/child
To represent nesting, we introduce parens:
/parent(parent-aux)/child(child-aux)
Angular Connect, London, October 2015
All Routes are First-class Citizens
Angular Connect, London, October 2015
Auxiliary Routes– Key Points
Angular Connect, London, October 2015
Angular Connect, London, October 2015
A tree of trees
AppCmp
Primary
IndexCmp
EmailCmp
SearchCmp
ComposeEmailCmp
Modal
ConfirmDeleteCmp
Angular Connect, London, October 2015
Trees of trees of trees of trees
Angular Connect, London, October 2015
Is Angular Recovered Extraterrestrial Technology?
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Angular Connect, London, October 2015
Component Router– In Conclusion
Provides a few simple parts: RouteConfig, RouterOutlet, and RouterLink – that combine in many ways.
Child and Auxiliary Routes fully compose – you can nest Child Routes inside Auxiliary Routes and vice-versa.
Linking DSL makes navigation robust, easy.
No scientific proof that Angular was created by aliens, but I believe the proof is out there.
Angular Connect, London, October 2015
The End
Thanks!
Angular Connect, London, October 2015