This question already has answers here:
Apply CSS to active router link [Angular 2]
(3 answers)
Closed 2 years ago.
I am creating a angular page which uses mat-tab-nav-bar and mat-tab-link.
dashborad.component.html
<div><nav mat-tab-nav-bar>
<a mat-tab-link [routerLink]="['/home']">Home</a>
<a mat-tab-link [routerLink]="['/admin']">Admin</a>
<a mat-tab-link [routerLink]="['/order']">Orders</a>
</nav></div>
<div><router-outlet></router-outlet></div>
AppRoutingModule
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { HomeComponent} from './components/home/home.component';
import { AdminComponent} from './components/admin/admin.component';
import { OrdersComponent} from './components/orders/orders.component';
const routes: Routes = [
{path: 'dashboard', component: DashboardComponent ,
children: [
{path: 'home', component: HomeComponent},
{path: 'admin', component: AdminComponent},
{path: 'order', component: OrdersComponent},
{path: '', redirectTo: 'home', pathMatch: 'full'}
]
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
I am able to get page as I want except one thing. When the page gets loaded it shows the default page but the tab is not showing as selected. When I click a tab it becomes active and shows the same page.So would like to know how to achieve the requirement.
You can use routerLinkActive attribute for the same. Where this attribute adds a class name to active element and then you can add CSS to that class
Find the syntax:
<a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
Css:
.active-link
{
Color: Blue;
Font-size: 17;
}
Related
I am using angular material design for making a website where I am unable to open home of side-bar. Please suggest me any solution.
https://stackblitz.com/edit/webkotactechsan-akntkf
used angular material design
<mat-nav-list>
<mat-card class="sidemenu">
<mat-list-item routerLink="home" routerLinkActive="active" >
<button mat-mini-fab color="primary" aria-label="Example icon-
button">
<mat-icon>home</mat-icon>
</button>
<span class="title"><b>Home</b></span>
</mat-list-item>
</mat-card>
unable to open home of side-bar
changes you need to do
change class name to export class HomeComponent in home.component.ts
spelling of home.component.scss is wrong, please correct it.
app.module.ts
import 'hammerjs';
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { FormsModule } from '#angular/forms';
import { RouterModule, Routes } from '#angular/router';
import { AppMaterialModule } from './app.material.module';
import { AppComponent, DialogContentComponent } from './app.component';
import { HomeComponent } from './home/home.component'
const appRoute: Routes = [
{ path: 'home', component: HomeComponent }
];
#NgModule({
imports: [
BrowserModule,
FormsModule,
AppMaterialModule,
BrowserAnimationsModule,
RouterModule.forRoot(appRoute)
],
declarations: [AppComponent, DialogContentComponent, HomeComponent],
entryComponents: [DialogContentComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
Changes I did in this file.
a) - added import { RouterModule, Routes } from '#angular/router';
b) - added import { HomeComponent } from './home/home.component'
c) -
const appRoute: Routes = [
{ path: 'home', component: HomeComponent }
]
;
d) - added RouterModule.forRoot(appRoute).
e) - added HomeComponent in declarations.
Then add <router-outlet></router-outlet> in your app.component.html.
Let me know if you have any doubt.
Please add routes in AppModule
RouterModule.forRoot([
{ path: 'home', component: HomeComponent },
{ path: '', redirectTo: 'home', pathMatch: 'full' },
],{onSameUrlNavigation: 'reload'}),
Live Example: Stackblitz
There is something you need to do to solve this problem and implement some angular way to manage components
1. Implement routing: The reason behind it, when you click on home, you need to go some router. So, we implement routing to solve this problem.
const appRoute: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'home'},
{ path: 'home', component: HomeComponent },
{ path: 'birthday', component: BirthdayComponent}
];
In the above code, we took two components for example purpose. When we call that route, it loads that component. For example we go home route it loads home component.
2. Divide into components: We are implementing single page application. So, we don't need to copy and paste all the sidenav, topbar in all components.
We kept those sidenav and topbar in app components and load app-content into router-outlet. you can see your inside codes of app-component in home and birthday component.
<div class="app-content">
<router-outlet></router-outlet>
</div>
3. Change routerLink to home and birthday, so that we need to show home, it loads home components and when we need to show birthday, it loads birthday component.
and finally thanks to piyush jain for solving common mistakes of your code.
I am attempting to build my first ever app using nativescript. I am going through the docs but not sure what I'm missing so I can't fix it.
I have the following structure:
- app
-- app-routing.module.ts
-- app.component.html
-- app.component.ts
-- app.css
-- app.module.ts
- home
-- home.component.css
-- home.component.html
-- home.component.ts
- restaurant
-- restaurant.component.css
-- restaurant.component.html
-- restaurant.component.ts
The thing is, I am trying to make it so that when someone taps on an element in the home.component.html:
<Image class="h3 m-5" col="0" row="0" src="~/images/beet-logo.jpg" (tap)="visitRestaurant()" height="87" width="80"></Image>
They are redirected to the restaurant.component.html page.
I defined the tap event as shown up there and then I have on my home.component.ts the following:
import { Router } from "#angular/router";
import { Component, OnInit } from "#angular/core";
#Component({
selector: "Home",
moduleId: module.id,
templateUrl: "./home.component.html",
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(private router: Router) {
}
visitRestaurant() {
this.router.navigate(["/restaurant"]);
}
ngOnInit(): void {
}
}
When I click it, it fails though with the error:
ERROR Error: Uncaught (in promise): Error: Cannot match any routes.
URL Segment: 'restaurant'
I thought about adding the route here and also into app-routing.module.ts but whenever I try I get cannot find name: RestaurantComponent. So I assume I need to export the component somewhere but not sure where or how.
Can you guys help me?
This is my app-routing-module.ts in case it's useful:
import { NgModule } from "#angular/core";
import { Routes } from "#angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router";
const routes: Routes = [
{ path: "", redirectTo: "/home", pathMatch: "full" },
{ path: "home", loadChildren: "./home/home.module#HomeModule" }
];
#NgModule({
imports: [NativeScriptRouterModule.forRoot(routes)],
exports: [NativeScriptRouterModule]
})
export class AppRoutingModule { }
Here's my restaurant.component.ts code:
import { Router } from "#angular/router";
import { Component, OnInit } from "#angular/core";
#Component({
selector: "Restaurant",
moduleId: module.id,
templateUrl: "./restaurant.component.html",
styleUrls: ['./restaurant.component.css']
})
export class RestaurantComponent implements OnInit {
constructor(private router: Router) {
}
ngOnInit(): void {
}
}
You need to add a route for /restaurant. For example, you might do:
const routes: Routes = [
{ path: "", redirectTo: "/home", pathMatch: "full" },
{ path: "home", loadChildren: "./home/home.module#HomeModule" },
{ path: "restaurant", component: RestaurantComponent }
];
Additionally, you'll want to make sure your export/import statements appear appropriately.
Within restaurant.component.ts:
#Component({ ... })
export class RestaurantComponent { ... }
Within app-routing.module.ts:
import { RestaurantComponent } from ' ... ';
Using #angular/router": "3.4.7".
Proposed solution here doesn't work anymore.
/**
The ProductComponent depending on the url displays one of two info
components rendered in a named outlet called 'productOutlet'.
*/
#Component({
selector: 'product',
template:
` <router-outlet></router-outlet>
<router-outlet name="productOutlet"></router-outlet>
`
})
export class ProductComponent{
}
#NgModule({
imports: [
CommonModule,
RouterModule.forChild([
{
path: 'product',
component: ProductComponent,
children: [
{
path: '',
component: ProductOverviewComponent,
outlet: 'productOutlet'},
{
path: 'details',
component: ProductDetailsComponent,
outlet: 'productOutlet' }
]
}
]
)],
declarations: [
ProductComponent,
ProductHeaderComponent,
ProductOverviewComponent,
ProductDetailsComponent
exports: [
ProductComponent,
ProductHeaderComponent,
ProductOverviewComponent,
ProductDetailsComponent
]
})
export class ProductModule {
}
Manual navigation works as expected
http://localhost:5000/app/build/#/product-module/product (correctly displays overview component in named outlet)
http://localhost:5000/app/build/#/product-module/product/(productOutlet:details)
(correctly displays details component in named outlet)
THE PROBLEM
Cannot figure out the correct way to perform programatical navigation:
this.router.navigateByUrl('/(productOutlet:details)');
this.router.navigate(['', { outlets: { productOutlet: 'details' } }]);
Following errors occur:
Error: Cannot match any routes. URL Segment: 'details'.
You can navigate programatically like this
this.router.navigate([{ outlets: { outletName: ['navigatingPath'] } }], { skipLocationChange: true });
Note: skipLocationChange is use to hide the url from the address bar.
Refer the official document : https://angular.io/guide/router
You can try relative navigation as
this.router.navigate(['new'],{relativeTo:this.route})
For this you will have to inject current router snapshot and Activated route in component as
import { Router,ActivatedRoute } from "#angular/router";
constructor(private router:Router,private route:ActivatedRoute ){}
I am fairly new to Angular 2 and having a problem with Routing. I have just started to explore the Routing. I will explain the structure and what I have achieved so far,
app.router.ts
import { ModuleWithProviders } from '#angular/core'
import { Routes, RouterModule } from '#angular/router'
import { AppComponent } from './app.component';
import { LoginComponent } from "../app/login/login.component"
export const router: Routes = [
{ path: '', component: LoginComponent },
{ path: 'login', component: LoginComponent },
{ path: 'dashboard', component: AppComponent }
];
export const routes: ModuleWithProviders = RouterModule.forRoot(router);
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import {UiSwitchModule} from 'angular2-ui-switch'
import { AppComponent } from './app.component';
import { AllReportsComponent } from "../app/all-reports/all-reports.component"
import { AvailableReportsComponent } from "../app/available-reports/available-reports.component"
import { NextReportsComponent } from "../app/next-reports/next-reports.component"
import { UrlsComponent } from "../app/urls/urls.component"
import { LoginComponent } from "../app/login/login.component"
import { TaskApi } from "../app/api/TaskApi"
import { routes } from "../app/app.router"
#NgModule({
imports: [
BrowserModule,
FormsModule,
UiSwitchModule,
HttpModule,
routes
],
declarations: [
AppComponent,
AllReportsComponent,
AvailableReportsComponent,
NextReportsComponent,
UrlsComponent,
LoginComponent
],
bootstrap: [AppComponent]
})
export class AppModule {
}
app.html
<div>
<all-reports></all-reports>
<available-reports></available-reports>
<next-reports></next-reports>
<urls></urls>
</div>
app.component.ts (very simple)
import { Component } from "#angular/core"
#Component({
templateUrl: '../app/app.html'
})
export class AppComponent {
}
and login.component.ts
import { Component } from '#angular/core';
import { TaskApi } from '../api/TaskApi';
import * as models from '../model/models';
#Component({
styleUrls: ['/app/css/login.css'],
templateUrl: '../../app/login/login.html',
providers: [TaskApi]
})
export class LoginComponent {
}
Now it can be seen that I am using multiple directives on app.html and all the respective components are working fine.
The problem I am facing is when I introduce Routing then I am able to understand where to use "router-outlet". I have used it on Index.html but it does not work and gives error about ng-component. So to just test around I have used following in Index.html,
<body>
<base href="/">
<ng-component></ng-component>
</body>
After I do this then my AppComponent is displayed by default where the LoginComponent should be displayed by default. On console, It also gives me error "Error: Cannot find primary outlet to load 'LoginComponent'"
Kindly guide me if I am using 4 directives on App.html as mentioned above then in that case how the routing will work. To summarize, I want to display Login page on localhost:3009/login and localhost:3009 and I want to display Home page (app.html) in localhost:3009/dashboard and app.html is using 4 directives to display 4 child components on it.
Angular Routing
Since Angular is single page application the routing functionality
helps to display different view in single page.
How to use router to change view?
since app.component.html is main view for most user. Iam also consider app.component.html as main view.
Router-outlet
Router-outer helps to load the change in our angular application.
app.component.html
<router-outlet></router-outlet>
Set AppComponent Default page as router-outlet and create new Dashboard.component.html in your main view.
router.ts
import { ModuleWithProviders } from '#angular/core'
import { Routes, RouterModule } from '#angular/router'
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard.component';
import { LoginComponent } from "../app/login/login.component"
export const router: Routes = [
{ path: '', component: LoginComponent },
{ path: 'login', redirectTo: '', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent }
];
export const routes: ModuleWithProviders = RouterModule.forRoot(router);
The problem with your code is that there is no 'router-outlet', so angular doesn't understand where to display the view.
The 'router-outlet' directive marks where the router displays a view.
In your code, since in app.component.ts you are using app.html so you should use <router-outlet> </router-outlet> in that HTML file.
Your app.html file should look like this:
<router-outlet> </router-outlet>
These below things should not be used in the app component HTML file. They should be used in their the corresponding components.
<all-reports></all-reports>
<available-reports></available-reports>
<next-reports></next-reports>
<urls></urls>
For further understanding, please refer to the official documentation of Angular2. They have explained it pretty well here https://angular.io/docs/ts/latest/guide/router.html
How to manage nested link in angular2.
for eg. I have two file :
app.component.ts
import { Component, forwardRef } from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import {HTTP_PROVIDERS} from 'angular2/http';
import 'rxjs/Rx';
import { HeroService } from './hero.service';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
import { TestComponent } from './test.component';
import { HeroDetailComponent } from './hero-detail.component';
import { LinkComponent } from './link.ts'
#Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<link111></link111>
<router-outlet></router-outlet>
`,
styleUrls: ['app/app.component.css'],
directives: [ROUTER_DIRECTIVES, forwardRef(() => LinkComponent)],
providers: [
HTTP_PROVIDERS,
ROUTER_PROVIDERS,
HeroService
]
})
#RouteConfig([
{
path: '/dashboard',
name: 'Dashboard',
component: DashboardComponent,
useAsDefault: true
},
{
path: '/detail/:id',
name: 'HeroDetail',
component: HeroDetailComponent
},
{
path: '/heroes',
name: 'Heroes',
component: HeroesComponent
},
{
path: '/test',
name: 'Test',
component: TestComponent
}
])
export class AppComponent {
title = 'Tour of Heroes';
}
link.ts
import {Component} from 'angular2/core';
import { ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
#Component({
selector:'link111',
template:`
<nav>
<a [routerLink]="['Dashboard']">Dashboard</a>
<a [routerLink]="['Heroes']">Heroes</a>
<a [routerLink]="['Test']">Test</a>
</nav>
`,
directives: [ROUTER_DIRECTIVES],
providers: [ROUTER_PROVIDERS]
})
export class LinkComponent {
}
When [routerLink] define in app.component.ts in place of link111 tag it works, but when i separate it into different file it doesn't work.
please help me, Thanks.
When [routerLink] define in app.component.ts in place of link111 tag it works, because angular look routing from the
main root file(that is app.ts in your case), but when you separate it into different file it doesn't work because
than routing is defined in the root file but you are calling from childern (i.e not from parent). so to resolve this
change this like this -
<a [routerLink]="['./Dashboard']">Dashboard</a>
<a [routerLink]="['./Heroes']">Heroes</a>
<a [routerLink]="['./Test']">Test</a>
because If the route begins with ./, the router will look up the current components childern route from the root of the app.
From officials -
The first route name should be prepended with /, ./, or ../. If the route begins with /, the router will look up the route from the root of the app. If the route begins with ./, the router will instead look in the current component's children for the route. And if the route begins with ../, the router will look at the current component's parent.
for more info refer this -
https://angular.io/docs/ts/latest/api/router/RouterLink-directive.html
How to use child routes in Angular 2.
Angular 2 router examples + #RouteConfig typing support