Angular 2 — Components and Router + Angular Material
My last post shows the setup process for Angular 2 + Angular Material using Angular CLI. In this blog post, we are going to layout the high level component architecture for the app and code the header, router and folder structure for a feature component. Below is high level hierarchal representation of our components (I have prefixed our app components with Hn). As we get more into the hackernews api details we will revisit our components architecture.
Every developer/team splits components in what makes sense to them and there is no one way splitting in component. You can go as granular as you need at to level of a label component in a form or higher level as you see fit.
In the diagram, I have split the components into SmartComponents
and PresentationalComponent
.
Smart Components or Container Components are components which our tied to applications, interacts with the service and holds the data of that component.
Presentational Components or Dumb Components are pure visual components which gets data passed on to them using @Input
. In our app we will keep all our smart components under containers
folder under each feature module and presentational components under component
unless if its reused then we will create a shared
folder, we will see this later.
I have split the app on the top level as HnHeaderComponent
and RouterOutlet
which will display the components according to the current route of the app. The routes I have planned are mimicking HackerNews.
/newest -> HnNewestComponent
/shows -> HnShowsComponent
/newcomments -> HnCommentsComponent
/story/:id -> HnStoryDetailsComponent
/ask -> HnAskComponent
/jobs -> HnJobComponent
Then each of the smart component has presentational component under them. Alright lets start coding our components and their hierarchy starting fromHnHeaderComponent.
Open angular-cli.json
and change the prefix
to hn
and styleExt
to scss
. Lets generate our header component.
ng g component header
This will generate a component with needed files as below
Move our header section from app.component.html
and app.component.scss
to header.component.html
and header.component.scss
.
If you check your app.module.ts
angular CLI has already imported the Header Components and added to declaration as part of the generator process. The last step is to add the header component to app.component.html
<hn-header></hn-header>
The browser should have reloaded automatically with our changes and you should be able to see the app similar to before our small refactor.
I am splitting each of the major section under the router-outlet
as a module. Lets use angular CLI to generate them
ng g module newest
installing component
create src/app/newest/newest/newest.component.scss
create src/app/newest/newest/newest.component.html
create src/app/newest/newest/newest.component.spec.ts
create src/app/newest/newest/newest.component.ts
update src/app/newest/newest.module.tsmkdir src/app/newest/containersng g component newest/containers/newest
installing component
create src/app/newest/containers/newest/newest.component.scss
create src/app/newest/containers/newest/newest.component.html
create src/app/newest/containers/newest/newest.component.spec.ts
create src/app/newest/containers/newest/newest.component.ts
update src/app/newest/newest.module.ts
- Generating a module named
newest
- Create a directory named containers
- Generate a component newest under containers directory
Lets import the newest
module in our app. Open up the app.module.ts
// import
import { NewestModule } from './newest/newest.module';// add to the imports array in @NgModuleimports: [
BrowserModule,
MaterialModule.forRoot(),
NewestModule
],
Now time to create our routes for the app. We will start with routing to the newest component. Create a file app.routing.ts
under the src/app
. Refer docs for more detailed configuration.
import { Routes } from '@angular/router';
import { NewestComponent } from './newest/containers/newest/newest.component';export const routes: Routes = [
{
path: '',
redirectTo: '/newest',
pathMatch : 'full'
},
{
path: 'newest',
component : NewestComponent
}
];
Import defined routes into our app.module.ts
// import
import { routes } from './app.routing';
import { RouterModule } from '@angular/router';// imports in @NgModule
```
imports: [
BrowserModule,
MaterialModule.forRoot(),
RouterModule.forRoot(routes),
NewestModule
],
Open app.component.html
and add <router-outlet></router-outlet>
. This will be location where the router will load the component into.
<hn-header></hn-header>
<router-outlet></router-outlet>
Open header.component.ts
and add routerLink
for the New
nav item.
<li routerLink="/newest">New</li>
We are creating a route newest
which loads the NewestComponent
. If the app loads with no route specified we are telling the router to redirect it to newest by default. Launch the app with ng serve
and go to localhost:4200
. You should see the below
In the above screenshot, you can see even though we entered localhost:4200
the app has redirect to localhost:4200/newest
as it is our default route specified in the router config. On the right, you can notice that the hn-newest
component is loaded below the router outlet. As we add new routes, that will be switched according to the configuration.
In the post, we have covered
- High level architecture of our app.
- Smart vs Presentational Components
- Folder structure for our components
- Setup router configuration and router link
- Set default route for the app
You can go ahead and setup the routes for the rest of the sections of the nav similarly and verify the navigation between different routes.
In the next post we will see setup for Firebase and getting the newest stories from firebase for HackerNews.