I have a main parent component that contains a built-in top nav, a separate sidebar nav component and a main content div that houses the <router-outlet> for the main component. I'm trying to get my head around how to have the links inside child nav component to change the router-outlet in the parent main component.
```
Main Component
#Component({
selector: 'app',
templateUrl: 'mainComponent.html',
encapsulation: ViewEncapsulation.None,
directives: [ROUTER_DIRECTIVES,ChildSidenav],
})
#RouteConfig([
{ path: '/', component: HomeCmp, as: 'Home' }, //for top nav
{ path: '/about', component: AboutCmp, as: 'About' }, //for top nav
{ path: '/user', component: UserCmp, as: 'User'}, //for top nav
{ path: '/data/...', component: SidenavBasicUsage, as: 'Data'}, //link in child component
{ path: '/dates', component: SelectDatesComponent, as: 'Dates'}, //link in child component
{ path: '/edit/paths', component: EditPathsComponent, as: 'EditPaths'}, //link in child component
{ path: '/edit/filters', component: EditFiltersComponent, as: 'EditFilters'}, //link in child component
])
export class AppCmp {}
Child Component
#Component({
selector: 'left-control',
templateUrl: 'sidebar.component.html',
moduleId: module.id,
directives: [ROUTER_DIRECTIVES],
})
#RouteConfig([
{path: '/',name: 'Data',component: SelectDataComponent,useAsDefault: true},
{path: '/dates',name: 'Dates',component: SelectDatesComponent},
{path: '/edit/paths',name: 'EditPaths',component: EditPathsComponent},
{path: '/edit/filters',name: 'EditFilters',component: EditFiltersComponent}
])
export class SideNavComponent{}
```
I haven't tried all these methods but I think they should work:
import {Router} from 'angular2/router'
...
constructor(private router:Router) {}
someMethod() {
this.router.parent.navigate(['About']);
this.router.navigate(['/About']);
this.router.navigate(['../About']);
}
With [routerLink]="..." it works the same (except the first example)
Related
I have one component where I want to show data according to the one of the categories.
categories - [sport, cars, fashion, politics].
In my NewsCategoriesComponent I need to show changed data when I'm clicking on the nav buttons.
How can I change data of component after clicking on nav buttons?
here is my routing
const routes: Routes = [
{path: '', component: DashboardComponent},
{path: 'category', component: NewsCategoriesComponent},
{path: '**', component: DashboardComponent}
];
You could pass the category as a parameter in your route:
const routes: Routes = [
{path: '', component: DashboardComponent},
{path: 'category/:category', component: NewsCategoriesComponent},
{path: '**', component: DashboardComponent}
];
Then read the parameter from the route in the NewsCategoriesComponent:
import { Component } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-news-categories',
templateUrl: './news-categories.component.html',
styleUrls: ['./news-categories.component.css']
})
export class NewsCategoriesComponent {
category: string;
constructor(private actRoute: ActivatedRoute) {
this.category = this.actRoute.snapshot.params.category;
}
}
How to check which layout component currently active in Angular in app.component ?
Here Is example my app-routing.module.ts.
{
path: '',
component: FrontComponent,
children: [
{
path: '',
redirectTo: 'login',
pathMatch: 'full'
},
{
path: 'login',
component: LoginComponent
}
]
},
{
path: '',
component: MainComponent,
canActivate: [AuthGuard],
children: [
{
path: 'dashboard',
component: DashboardComponent
},
{
path: 'message-list',
component: MessageListComponent,
}
]
}
Now I want to check layout component in app.component such as if it is 'FrontComponent' or 'MainComponent' . Because I want to perform some activity based on layout component. I have searched other questions but could not get required answer. can anyone please help me out? Thanks in advance.
Specifically looking to check layout frontcomponent is active in app.component.ts
You can learn it by looking at the URL with
import { Component } from '#angular/core';
import { Router } from '#angular/router';
#Component({
template: ''
})
export class Component {
constructor(private router: Router) {}
ngOnInit() {
if ( this.router.url.indexOf('login') != -1) {
console.log('Father is FrontComponent');
}
}
}
You can make a service where you store the current layout component name string, and this variable gets overridden when switching to the other component.
I am a beginner in angular2.
I try to use routes in a CRUD app. My problem are the nested routes. Chart example :
AppComponent
/ \
MealListComponent DishListComponent
\
DishEditComponent <--- Must have DishList template
The link / and \ respresent routes.
Problem : I want my DishEditComponent template is not include on DishListComponent template.
You can test app on http://plnkr.co/edit/g7NaoVd5BkGtSmr8ZkFW?p=preview go to Liste Dish link, then to Add dish link.
You'll see both Dish List title and Dish Edit orr Add title because DishEditComponent template is included in DishListComponent template by router-outlet tag, but I want that only Dish Edit or Add title displayed.
Do you know a way to avoid nested routes ?
You can try using asyncRoute.
Here is explanation for it.
import {Component, View, bootstrap} from 'angular2/angular2';
import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from 'angular2/router';
import {Home} from './components/home/home';
import {About} from './components/about/about';
#Component({
selector: 'app'
})
#RouteConfig([
{ path: '/', component: Home, name: 'home' },
{ path: '/about', component: About, name: 'about' }
])
#View({
templateUrl: './app.html',
styleUrls: ['./app.css'],
directives: [ROUTER_DIRECTIVES]
})
class App {}
bootstrap(App, [ROUTER_PROVIDERS]);
Here’s the implementation of the About component:
import {Component, View, CORE_DIRECTIVES} from 'angular2/angular2';
import {NameList} from '../../services/NameList';
#Component({
selector: 'about',
providers: [NameList],
templateUrl: './components/about/about.html',
directives: [CORE_DIRECTIVES]
})
export class About {
constructor(public list: NameList) {}
addName(newname):boolean {
this.list.add(newname.value);
newname.value = '';
return false;
}
}
The class, which implements RouteDefinition and allows asynchronous loading of the component associated with given route. This allows on demand loading of the component’s dependencies as well. Here’s now our definition will look like with AsyncRoute:
#RouteConfig([
{ path: '/', component: Home, name: 'home' },
new AsyncRoute({
path: '/about',
loader: () => System.import('./components/about/about').then(m => m.About),
name: 'about'
})
])
Basically we register two routes: - A regular route - Async route. The async route accepts as argument a loader. The loader is a function that must return a promise, which needs to be resolved with the component that needs to be rendered.
I found the solution.
1. I must remove this line in DishListComponent template :
<router-outlet></router-outlet>
2. Replace line :
<a [routerLink]="['DishEdit']">Add dish</a>
by this line :
<button (click)="addDish()">Add dish</button>
3. Add import :
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, Router } from '#angular/router-deprecated';
4. Update DishListComponent constructor :
constructor(private router: Router) {
}
5. Add this method in DishListComponent :
addDish() {
let link = ['DishEdit', {}];
this.router.navigate(link);
}
6. Remove PROVIDERS in DishListComponent
Final code
Final DishListComponent
#Component({
selector: 'dish-list',
directives: [ROUTER_DIRECTIVES],
template:`
<h1>Dish List</h1>
<button (click)="addDish()">Add dish</button>
<main>
</main>
`
})
export class DishListComponent {
constructor(private router: Router) {
}
addDish() {
let link = ['DishEdit', {}];
this.router.navigate(link);
}
}
The final RouteConfig
#RouteConfig([
{
path: '/dish-list',
name: 'DishList',
component: DishListComponent
//useAsDefault: true
},
{
path: '/dish-edit',
name: 'DishEdit',
component: DishEditComponent
},
{
path: '/meal-list',
name: 'MealList',
component: MealListComponent
}
])
The plunker link : http://plnkr.co/edit/LsLdc0efJtPaEbASWPek?p=preview
I hope it will help !
I'm still working on a project using Angular2.
If you want more details about why I need to do what I'm going to explain, please refer this issue.
I have an AppComponent which is bootstraped via bootstrap. It's a very simple component :
#Component({
selector: 'app-view',
directives: [ Devtools, MainComponent ],
template: `
<ngrx-devtools></ngrx-devtools>
<main-cmp></main-cmp>
`
})
export class AppComponent { }
This component includes another one : MainComponent (via the main-cmp selector). For some reasons, I want to set up my routing in MainComponent.
Here is the code :
#Component({
selector: 'main-cmp',
directives: [ ROUTER_DIRECTIVES, NavComponent ],
template: `
<h1>App</h1>
<nav-cmp></nav-cmp>
<router-outlet></router-outlet>
`
})
#RouteConfig([
{ path: '/home', name: 'Home', component: HomeComponent, useAsDefault: true },
{ path: '/medias', name: 'Medias', component: MediasComponent }
])
export class MainComponent {
constructor (private router:Router, private store:Store<AppStore>) {
router.subscribe(url => store.dispatch(changeUrl(url)));
}
}
Finally, MainComponent includes NavComponent which is a very basic nav.
The thing is, with this setup, I encounter this issue :
EXCEPTION: Component "AppComponent" has no route config. in [['Home'] in NavComponent#2:15].
Of course, if I move my router's logic to AppComponent, everything works well.
So my question is : is there a way to do routing stuff into another component than the one which is bootstraped ?
Thanks :).
It appears that it's not possible because the generate method of the RouteRegistry class explictly relies (hardcoded) on the root component. See this line in the source code:
https://github.com/angular/angular/blob/master/modules/angular2/src/router/route_registry.ts#L345
Here is the code that trhows the error:
RouteRegistry.prototype._generate = function(linkParams,
ancestorInstructions, prevInstruction, _aux, _originalLink) {
(...)
var parentComponentType = this._rootComponent; // <----
(...)
var rules = this._rules.get(parentComponentType);
if (lang_1.isBlank(rules)) { // <----
throw new exceptions_1.BaseException("Component \"" +
lang_1.getTypeNameForDebugging(parentComponentType) +
"\" has no route config.");
}
(...)
};
This method is indirectly used from the _updateLink method of the RouterLink directive.
Here is the corresponding stack trace:
RouteRegistry._generate (router.js:2702)
RouteRegistry.generate (router.js:2669)
Router.generate (router.js:3174)
RouterLink._updateLink (router.js:1205)
See the plunkr I used to debug your problem: https://plnkr.co/edit/8JojtgZmc8kA9ib6zvKS?p=preview.
How about a workaround - use root as a child route?
#Component({
selector: 'app',
directives: [ ROUTER_DIRECTIVES ],
template: `
<router-outlet></router-outlet>
`
})
#RouteConfig([
{path: '/...', as: 'Main', component: MainComponent, useAsDefault: true }
])
export class App { }
#Component({
selector: 'main-cmp',
directives: [ ROUTER_DIRECTIVES ],
template: `
<h1>App</h1>
<router-outlet></router-outlet>
`
})
#RouteConfig([
{ path: '/home', name: 'Home', component: HomeComponent, useAsDefault: true },
])
export class MainComponent { }
My Routing isn't working in Angular2, to demonstrate the point, I have put the same component as the destination for both the root of my site and /login. The component works at http://localhost:3000, but at http://localhost:3000/login, I just get a notice "Cannot GET /login".
app.component.ts:
import { Component } from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import {TodoService} from './todo/services/todo.service';
import { TodoCmp } from './todo/components/todo.component';
import { LoginComponent } from './user/components/login.component';
import { UserService } from './user/services/user.service';
#Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<router-outlet></router-outlet>
`,
styleUrls: ['client/dev/todo/styles/todo.css'],
directives: [ROUTER_DIRECTIVES],
providers: [
ROUTER_PROVIDERS,
TodoService
]
})
#RouteConfig([
{
path: '/',
name: 'TodoCmp',
component: TodoCmp,
useAsDefault: true
},
{
path: '/login',
name: 'TodoCmp',
component: TodoCmp
}
])
export class AppComponent {
title = 'ng2do';
}
Here is a link to my index file.
What have I done wrong?
Two routes in one #RouteConfig(...) can't have the same name:
#RouteConfig([
{
path: '/',
name: 'TodoCmp',
component: TodoCmp,
useAsDefault: true
},
{
path: '/login',
name: 'TodoCmp', <!-- <<<== should be 'Login' instead of 'TodoCmp'
component: TodoCmp
}
])
You should move ROUTER_PROVIDERS to bootstrap() (like HTTP_PROVIDERS)