In case of complex projects it is often expected to provide different layouts adapted to the needs of users – the logged-in user requires different UI elements than the guest. We have to customise the appearance of applications time and again taking into account many various aspects. Angular allows you to organise the presentation layer to easily handle multiple layouts.
What we are going to build
Our application will provide two separate layouts – one served on a landing page view, the other used on a dashboard view. In this post we will display the default contents, just to present how to serve different components in isolated layouts.
To see the version with a horizontal navigation and a footer for the landing page and a vertical navigation for a dashboard, check out the Enhance the presentation layer of your multi-layout Angular app post, where all views are complemented with the appropriate html code and Bootstrap classes. The finished project is available in the following GitHub repository: little-pinecone/angular-multi-layout-scaffolding.
|I try to keep the project up to date. Visit the releases list to keep track of the current versions of frameworks and libraries used.|
- Angular CLI – a command line interface tool that generates projects, components, modules, services.
I’m working on:
- We will work on a freshly created Angular 6 project that uses the
scsspreprocessor and Bootstrap styles. To learn how to create such a project, visit the How to create a new Angular project post. If you want to change the preprocessor, read the How to change a CSS preprocessor in an Angular project post.
layout folder will contain all components used to assemble the guest and authorised layouts and a component that is shared by both of them –
PageContent. The actual content of two views – the landing page and the dashboard – is going to be stored in the
pages folder. We are also going to create a
routing module, so the layout served depends on the url.
You won’t find any authorisation logic in this example.
The final project
src/ directory tree:
Angular CLI will create all parent folders for generated components – just remember to give the full path for a component.
Enable serving the content of different pages
To avoid code repetition and facilitate handling pages, we will create a component accessible for both layouts – the
Replace the default content of the
page-content.component.html with the following code:
The work done in this section is contained in the commit 9d92b44a7c2b620e0d5391b7cd89ecf47cb88b58.
Manage the guest layout
Create the layout components
Create the component for the top navigation:
Create the component for the footer:
Bind the navigation, page content and footer within the guest layout:
Replace the content of the
guest-layout.component.html with the following code:
Generate the component for our landing page:
Add routing to a page with the guest layout
Prepare the routing module file
The following steps are well covered in the official Angular tutorial.
Let’s create a routing module in the main directory of the project:
Angular CLI will create required files in the
app/ folder and register the new module in the imports array of the
Add @NgModule.exports array with
RouterModule in it:
We will need two separate sections for routes, but for now we can handle only the guest layout. Import
LandingPageComponent and add the following route to the
RouterModule.forRoot(routes) to the @NgModule.imports array:
Do not display the default Angular page
We want to change the content displayed on
http://localhost:4200/ – from the default Angular page to our landing page. Replace the content of
app.component.html with the following code:
Check out the landing page of your app on
The work done in this section is contained in the commit a5cb113c477777dd266457341313e070999d930e.
Make sure that the CLI is tracking changes, refresh the browser window with
Ctrl+F5 or restart the Angular server if you can’t see the effect.
Fix the tests
If you run the following command:
you will see that the default test set from
app.component.spec.ts fails. Let’s investigate the errors:
<router-outlet>is not recognised
Importing RouterTestingModule to the
app.component.spec.tsfiles provides the Router mock:
- A component with nested components
The guest-layout template have nested components – they should have their own tests so we can exclude them from testing in
guest-layout. Import Component, create mocks and add the mocked components to the
You can apply NO_ERRORS_SCHEMA instead, but it will hide other errors – missing components and attributes that you overlooked or misspelled.
- Missing html content
We altered the html that is tested- adjusting the content expected by tests fixes the problem. Furthermore, we can remove all tests from the
app.component.spec.tsfile – except the one testing the creation of the app:
PageContentComponent don’t have any logic or html elements to test – we only need to verify whether they were created. You can read more about testing components in the official guide.
The work done in this section is contained in the commit c4e7e2d570c6fed56a5db249325710f5b620074d.
If the errors remain, try terminating the testing process and run thecommand again.
Manage the layout for an authorised user
Create the component for the side navigation:
Bind the navigation and page content within the layout for and authorised user:
Replace the content of the
authorised-layout.component.html with the following code:
Generate a component for the dashboard page:
Add routing to the dashboard page
DashboardComponent and add the following route to the routes array:
Check out the authorised layout on
The work done in this section is contained in the commit 7fd037e2ea0ed74f176dd7a1edee6b3740560b80.
Update the tests
If you run the following command:
you will see that the tests from
authorised-layout.component.spec.ts fail. Again, we encounter the error caused by the nested components:
The authorised-layout template have nested components – they should have their own tests so we can exclude them from testing in
authorised-layout. Import Component, create mocks and add the mocked components to the
The work done in this section is contained in the commit 24cba57ee1b58b8c1abb6110212c6f78d71fd021.
If the errors remain, try terminating the process and run thecommand again.
What is next?
Add html content and styles to the landing page, dashboard and both layouts components. Check out the Enhance the presentation layer of your multi-layout Angular app post or visit the project repository to see how to style the pages: