I am having an Angular 2 application with several nested children view. But it will be displayed on the same page though several router-outlet
.
const routes: Routes = [
{
path: 'queue/:date/:offset/:type',
component: BundleListComponent,
resolve: {
response: BundleListResolve
},
children: [
{
path: ':bundleId', component: PointListComponent,
resolve: {
response: PointListResolve
},
children: [
{
path: ':pointId', component: TaskListComponent,
resolve: {
response: TaskListResolve
},
children: [
{
path: ':taskId', component: TaskDetailComponent,
resolve: {
response: TaskDetailResolve
}
},
{ path: '', component: EmptyComponent }
]
},
{ path: '', component: EmptyComponent }
]
},
{ path: '', component: EmptyComponent }
]
},
{
path: 'queue',
component: QueueRedirectComponent
}
}
So basically I can travel through the list of route
- /queue
- /queue/:date/:offset/:type
- /queue/:date/:offset/:type/:bundleId
- /queue/:date/:offset/:type/:bundleId/:pointId
- /queue/:date/:offset/:type/:bundleId/:pointId/:taskId
For example
#/queue/2017-01-05/480/20/57f4c26507b36e3684007b52/1/57fb0abb07b36e39d8e88df8/1
Imagine you have a page with some element:
- One UI portion showed a movie list
- The other portion shows a movie detail when clicking into an item in a movie list but display on the same page.
- Another portion to show a character detail when clicking into character name on movie detail, and also show on the same page.
- etc...
Basically, I can still click into movie list while I am viewing a character detail.
Searching for defining the name for each route but seem all the answer report this feature has already removed from Angular 2 final. In Angular 1 using UI Router, I can define the name for each route and can get the route very easily with built-in function state.is(ROUTE_NAME)
.
So what I am doing now is base on the window.location to get the URL and splitting this string by /
to get the number of parameters. But It's more hard-coded one.
Any experience on doing the same? How I can distinguish which route is currently active?
my answer is similar, but did in a different way, so I think it's good to post
What is different: I don't need to change anything on my routes, I did a service to track the deeper ActivatedRoute (inside or firstChild...firstChild)
create the service
then in app.component.ts I start the service (just to ensure it's always tracking)
and finally, take your route wherever service you are:
answering the question, you can just take the deeperActivatedRoute and check normally the snapshop.url, just as you would do in a component
I believe there is an issue with Scott's answer where he uses the ActivatedRoute inside the constructor of the service. This route won't get updated.
I thought of another solution which might peek your interest. It again comes down on using the
data
property on the routes, but now using another resolve service:You are going to need a
RouterConfig
like this, where for each route you add thestate: StateResolve
and a data object containing the state name:don't forget to add the StateResolve service to the providers array
Your
StateResolve
service will look something like this:Obviously you will need a
StateService
which has thesetState
method, but I guess from here it's pretty self-explanatory.Perhaps using a
resolve
guard is a bit eccentric, but if you think about it, you are trying to resolve data before you show the route. In this case, the state inside the data variable, so it does make sense to use theResolve
to access thedata
propertyCreate a service called
ActiveState
which willsubscribe
to changes to the router, usingrouter.events.subscribe
:Then on your route we add a simple value on the
data
param of the route calledstateName
for each state we want to name:Then when you inject
state : ActiveState
you can simple test the valuestate.is("Point")
Create a Service called
ActiveState
:In your resolvers such as
PointListResolve
...TaskListResolve
etc.So in the other resolvers update the
this.state.setActive("")
value as required.Then to determine which state you are in, inject
ActiveState
where you want to use the current state, such as in a@Component
, i.e.Notes:
Don't forget to register your
ActiveState
service as aProvider
in:Simpler - Non-Observable Version I've used an
Observable<string>
so changes to the active state can besubscribed
to, but this could be simplified to just be astring
if you don't want that functionality:Then when you inject
state : ActiveState
you can simple test the valuestate.is("Point")
I hope that's useful.
name
was removed quite some time ago from routes, but routes allow to add arbitrary dataThis code constructs a title from the names of all route segments. This could probably be simplified for your use case.
See also Changing the page title using the Angular 2 new router