Rendering a child route in the parent in Angular 4 - javascript

With Angular 2, I could make a child route render "over" its parent by defining an empty path and creating an essentially empty base component. I am trying to accomplish something similar with the new Angular router (version 4.3.1), but have hit a roadblock.
To reproduce my problem, here's a Plunker. The routes are defined as:
[{
path: '',
redirectTo: "/master",
pathMatch: "full"
}, {
path: 'master',
component: MasterComponent,
children: [{
path: 'detail/:value',
component: DetailComponent,
children: [{
path: 'subdetail',
component: SubDetailComponent
}]
}]
}]
When I navigate to a detail page, the master page is still visible because I have added a <router-outlet></router-outlet> to MasterComponent. What I need is to replace the master view with the detail. I can accomplish this by making detail/:value a sibling of master rather than a child, but this isn't logically correct in my application and breaks my breadcrumbs.
Is there any proper way to handle this kind of pattern, or will I have to pick a workaround, such as showing and hiding the intended route or manually specifying a dedicated "main" outlet for every link?
The only existing solution that comes close is to define a dummy parent component, but this only works one-level down. If my detail page has another sub-detail page that should also replace master, it gets very messy.
Is there any route-level flag I can set or design pattern to implement to elegantly accomplish this? I am an Angular 2 beginner, but I feel as though something like this should be simple.

First, there is no "new" router in 4.3.1. It's the same router from 2.x.
Second, there were a few changes I needed to make to your plunker to make it work appropriately. The key change was this in the master.component.ts:
<a [routerLink]="['/detail', 5]">
I added a slash. Without the slash it was looking for a route named master/detail/5
The route definition is now flat, so everything will appear "under" your main header.
export const routes: Routes = [
{
path: '',
redirectTo: 'master',
pathMatch: 'full'
},
{
path: 'master',
component: MasterComponent
},
{
path: 'detail/:value',
component: DetailComponent
}
];
The updated plunker is here: https://plnkr.co/edit/EHehUR6qSi248vQPDntt?p=preview

Related

how to use routerlink in angular?

I'm new in Angular but I came from various frameworks that are relevant to the Backend such as Django, I note that Angular has the same nature as Django routing a bit regardless that it belongs to client-side so, so I'm familiar with routing confused around how Angular handles routing and use router-link in the template in Angular.
there is my problem:
export const routes: Routes = [
{path: 'login', component: LoginComponent, outlet: "login"},
{path: 'signup', component: RegisterComponent, outlet: "register"},
]
when I'm trying to move to the login page by the following statement:
<a [routerLink]="['', {outlets: {login: ['login']}}]" ariaCurrentWhenActive="page" routerLinkActive="active">Signin?</a>
what is happening is that the link looks like this link when it displaying it in the inspect element:
/app/(login:login//register:signup)
my current page is /app/(register:signup) and all I want to do is to move to: /app/(login:login)
first of all, I want to know how to move to my target.
second: I want to understand the router link nature in angular and how it works if it is possible.

Navigate between outlet modals in Angular 5?

I can't handle navigation from one modal window to another.
I have routing module:
{
path: 'modal1',
component: Modal1Component,
outlet: 'modal',
}, {
path: 'modal2',
component: Modal2Component,
outlet: 'modal',
}
Main component: MainComponent and in its template i have
<router-outlet name="modal"></router-outlet>
So i am clicking a button that triggers
this.router.navigate([this.router.url, { outlets: {modal: 'modal1'} }]);
And in Modal1Component that is rendered i have a button for modal2. So i want to call modal2 from modal1. How can i tell router to go to the parent route and then call:
this.router.navigate([/* what should be here? */, { outlets: {modal: 'modal2'} }]);
It looks like you're just changing the outlet in your router.navigate, but the route itself is not actually changing. And I don't think you actually require a named outlet to do what you're trying to achieve.
When you use router.navigate, you can specify if you want to navigate relatively from somewhere using the ActivatedRoute class. To do so, you have two options :
navigate relatively from you current component and indicate in the path that you want to "go up" one level. Example :
this.router.navigate(['../modal2'], { relativeTo: this.activatedRoute });
navigate directly from you parent. I would personaly use this one but both works. Example :
this.router.navigate(['modal2'], { relativeTo: this.activatedRoute.parent });
I created a mini repo with an example of what (I think) you're trying to achieve on : stackblitz.
Hope that helps
Some service can be useful in this case, like in doc:
https://angular.io/guide/component-interaction

Angular 5: How to load multiple custom child components for a screen?

Background
I'm writing an enterprise application in Angular 5. One of the large screens I'm working on has many tabs and child components. A majority of clients will get the same version of the screen, but a client or two want custom changes under a couple of tabs.
Question
How do I dynamically load custom components for those couple of tabs where the client wants changes? I know I could use async lazy module loading to load a whole new screen specific for that client, but it seems it would be more efficient to only swap out the child components that have changes rather than the whole screen.
Async loading appears to be the way to go as you can use canLoad to not load unnecessary code for each client. At the child level, if you have multiple components at the same child level to swap, you could try to use named router outlets with async modules for the child components. However, I ran into a bug with async loading and the named router outlets.
Anyone have any other ideas?
Code
Here is the code for the routes I tried when exploring the above idea. The core screen is the parent level screen, async loaded.
export const routes: Routes = [
{
path: '',
component: CoreScreenComponent,
children: [
{
path: 'x-core',
loadChildren: "app/components/core-component-x/core-component-x.module#CoreComponentXComponent",
outlet: 'x'
},
{
path: 'x-client',
loadChildren: "app/components/client-component-x/client-component-x.module#ClientComponentXComponent",
outlet: 'x'
},
{
path: 'y-core',
loadChildren: "app/components/core-component-y/core-component-y.module#CoreComponentYComponent",
outlet: 'y'
},
{
path: 'y-client',
loadChildren: "app/components/client-component-y/client-component-y.module#ClientComponentyComponent",
outlet: 'y'
},
]
}];

Routing in angular 2

I have doubt in routing in angular2.
I have a login screen. After login dashboard and other pages had header and footer which will not be in login.
const routes: Routes = [
{
path:'',
redirectTo: '/login',
pathMatch: 'full'
},
{
path:'login',
loadChildren: './auth/auth.module#AuthModule',
},
{
path: 'dash',
loadChildren: './dash/dash.module#DashModule',
canActivate:[AuthGuard],
data: {
preload: true
}
},
{
path: 'project',
loadChildren: './project/project.module#projectModule',
canActivate: [AuthGuard],
data: {
preload: true
}
}
];
So its loading to the router-outlet in the app.component.html.
Currently I have to use the header component in all module html, like in dash.component.html
<ks-header></ks-header>
<router-outlet></router-outlet>
This router-outlet is a child outlet on which other dash related load.
Same like for other modules.
Is there any other effective way to show common header/sidebar?
I tried it in app.component.html like
<ks-header [userInfo] ="userInfo" [hidden]="isLogin"></ks-header>
<ks-sidebar [hidden]="isLogin"></ks-sidebar>
the islogin will determine logined or not. But I don't think it's a good idea.
You should use nested routes.
One for the base, as routeing between the template page and the login page.
The second and the nested one must be accomplished routeing between templated pages like
HOME, ABOUT, CONTACT ...
You can learn more about nested routes from here. So simple explanation.
And there is another question similar to yours. Namek's answer seems useful.

Angular2 useAsDefault not work for child route

I have been playing around with Angular2 route example which has child route as default route, but the example did not navigate to that default route: https://angular.io/resources/live-examples/tutorial/ts/plnkr.html
While the tutorial of Tour of Heroes which has not child route, useAsDefault was working normally: https://angular.io/resources/live-examples/router/ts/plnkr.html
Any sollution would be appreciated. Thanks in advance
Apparently nested useAsDefaults don't work, I'm not aware of that behavior. Note too that the problem is the useAsDefault in the parent route, not in the child.
You can fix that issue though by adding a redirectTo.
#RouteConfig([
{ path : '/', redirectTo : ['CrisisCenter'] }, // Here...
{ // Crisis Center child route
path: '/crisis-center/...',
name: 'CrisisCenter',
component: CrisisCenterComponent
},
{path: '/heroes', name: 'Heroes', component: HeroListComponent},
{path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent},
{path: '/disaster', name: 'Asteroid', redirectTo: ['./CrisisCenter', 'CrisisDetail', {id:3}]}
])
export class AppComponent { }
Note that I removed the extra useAsDefault. I'll file an issue so they can fix it in the docs.
Update 2
It isn't a mistake in the docs actually, it's a bug. I got the confirmation by #wardbell. There's already an issue filed for this bug.
So according to his comment the docs won't be updated (there's nothing to update, it's a bug!).
This issue was reported [...]. I left the doc as is, hoping that it will become correct soon.
Update
Here's the issue I filed. They'll tell us if it's a mistake in the docs or not (most likely, I'll bet on that). I'll update after they answer.

Categories