reason of using nested route for me is handling dynamically icon and back button for every page.i have abstract route because when i click to back button route params disappear and i put an abstract path to keep id and questionnaire type parameter in url.my abstract path is Questionaire.
const routes: Routes = [
{
path: '',
component: LayoutComponent,
children:[
{ path: 'Home', component: HomeComponent,data:{icon:'fa-home'} },
{ path: 'QuestionaireList', component: QuestionaireListComponent,data:{icon:'fa-list-ul',previousState:'/Home'} },
{ path: 'ModifyMetaContent/:metaContentId/:title', component: ModifyMetaContentComponent,data:{icon:'fa-database',previousState:'/MetaContentList'}}
{
path: 'Questionaire/:id',
children:[
{ path: 'MetaContentList', component: MetaContentListComponent,data:{icon:'fa-database',previousState:'/QuestionaireList'}}
]},
{
path: 'Questionaire/:questionnaireType',
children:
[
{ path: 'AddQuestionnaire', component: CreateQuestionnaireComponent,data:{icon:'fa-plus',previousState:'/QuestionaireList'}},
]},
{
path: 'Questionaire/:questionnaireType/:id',
children:[
{ path: 'UpdateQuestionnaire', component: EditComponent,data:{icon:'fa-pencil',previousState:'/QuestionaireList'} },
{ path: 'QuestionList', component: QuestionListComponent,data:{icon:'fa-pencil',previousState:'/QuestionaireList'} },
{ path: 'ImportQuestion', component: ImportQuestionComponent,data:{icon:'fa-plus',previousState:'/QuestionaireList'} },
]} ,
]},
];
MetaContentList.Component.html
<a class="ui labeled positive icon small button" [routerLink]="['/ModifyMetaContent','',questionnaireTitle]">
<i class="plus icon"></i>
new metaContent
</a>
i store previous url in snapshot.data.previousState
but when i click to ModifyMetaContent
i go to
localhost:4200/ModifyMetaContent/...
and when i click to back button , id
and questionnairetype
disappear from url.when i to click to ModifyMetaContent i expected go to :
localhost:4200/Questionaire/b8b55b42-f39f-4359-93d0-0260ddf3827f/MetaContentList/ModifyMetaContent/...
and when i click to back button i expected go to
.../Questionaire/b8b55b42-f39f-4359-93d0-0260ddf3827f/MetaContentList/ but url set to localhost:4200/MetaContentList
and this error occurred :
Cannot match any routes. URL Segment: 'MetaContentList'
i handle this case by nested states of angularjs ui-router.is any solution to this issue in angular2+ router ?
i solve this issue by change route structure and add a function for previousstate link in appcomponent:
my router:
const routes: Routes = [
{
path: '',
component: LayoutComponent,
children:[
{ path: 'Home', component: HomeComponent,data:{icon:'fa-home',previousState:[]} },
{ path: 'QuestionaireList', component: QuestionaireListComponent,data:{icon:'fa-list-ul',previousState:['/Home']} },
{ path: 'Questionaire/:id',children:[
{ path: 'MetaContentList', component: MetaContentListComponent,data:{icon:'fa-database',previousState:['/QuestionaireList']}},
{ path: 'ModifyMetaContent/:metaContentId/:title', component: ModifyMetaContentComponent,data:{icon:'fa-database',previousState:['Questionaire','MetaContentList']}}
]},
{ path: 'Questionaire/:questionnaireType',
children:[{ path: 'AddQuestionnaire', component: CreateQuestionnaireComponent,data:{icon:'fa-plus',previousState:['/QuestionaireList']}}]},
{path: 'Questionaire/:questionnaireType/:id',
children:[
{ path: 'UpdateQuestionnaire', component: EditComponent,data:{icon:'fa-pencil',previousState:['/QuestionaireList']} },
{ path: 'QuestionList', component: QuestionListComponent,data:{icon:'fa-pencil',previousState:['/QuestionaireList']} },
{ path: 'ImportQuestion', component: ImportQuestionComponent,data:{icon:'fa-upload',previousState:['/QuestionaireList']} },
]} ,
]},
];
in my router 2 state is possible :
array.length
is bigger than 1 .for embedding route params i create a method in appcomponent:method for get lastchild :
getSnapshot(route: ActivatedRoute){
let lastChild = route;
while (lastChild.firstChild) {
lastChild = lastChild.firstChild;
}
return lastChild;
}
method for get previous state :
getPreviousUrl(a):string{
let previousState:string;
const previousStateLength=a.snapshot.data.previousState ? a.snapshot.data.previousState.length :null;
if(previousStateLength!==null){
if(previousStateLength<=1 )
{previousState=a.snapshot.data.previousState[0];}
else{
previousState='/';
let parentParams=[''];
let j:number=0;
let b=a;
while(b.parent){
b.parent.params.subscribe((params)=>{
Object.keys(params).map(key=>parentParams[j]+=params[key]+'/');
for(let i=0;i<previousStateLength-1;i++){
if(parentParams[j]!==undefined)
previousState+=a.snapshot.data.previousState[i]+'/'+parentParams[j];
}
})
b=b.parent;
j++;
}
previousState+=a.snapshot.data.previousState[previousStateLength-1];
}
return previousState;
}
}
and get data :
constructor(router:Router,route:ActivatedRoute) {
router.events
.filter(event => event instanceof NavigationEnd)
.subscribe(e => {
const lastChild=this.getSnapshot(route);
this.routerIcon = lastChild.snapshot.data.icon;
this.previousState=this.getPreviousUrl(lastChild);
});
its work for me bu i want to maximality improve it.