angularmultiview

How to work with multiple views in Angular 6


I am building a new Angular 6 app to replace an existing page. We want the page to keep the same layout and flow. This page has three columns. The first column is the parent, then the child, and grand child.

There are a couple of different paths that a user can take starting with the parent. They can click on an item in the list and view the details. However, the user could click a 'new' button in the parent and see a different view in the child.

At this point, I am not interested in routing as I don't really need a direct link to the child or grand child.

I am looking at routes with children and routing outlets. When I run the application, my parent path loads but I am not seeing the child and grand child. What did I do wrong here?

Here is what I have:

Routes

const routes: Routes = [
  { 
    path: '', 
    pathMatch: 'full',
    component: EmailListComponent, 
    outlet: 'list_panel',
    children: [
      { 
        path: '',
        pathMatch: 'full',
        component: EmptyComponent,
        outlet: 'action_panel'
      },
      { 
        path: '',
        pathMatch: 'full',
        component: EmptyComponent,
        outlet: 'detail_panel'
      }
    ]}
];

app.component.html

<table class="adminTable" 
      style="margin: 0 auto; min-width: 1100px; height: auto;">
  <tr>
    <td class="adminCell" 
        style="vertical-align:top; width:210px; padding:10px;">
      <router-outlet name="list_panel"></router-outlet>
    </td>

    <td class="adminCell" 
        style="vertical-align:top; width:290px; padding:10px;">
      <router-outlet name="action_panel"></router-outlet>
    </td>

    <td class="adminCell" 
        style="vertical-align:top; padding:10px;">
      <router-outlet name="detail_panel"></router-outlet>
    </td>
  </tr>
</table>

email-list.component.html

<p style="font-weight:bold; font-size:larger;">Campaigns</p>

<table id="campaignList" 
        style="width:100%; margin:0px; padding:0px; border:0px; border-collapse:collapse;">
  <tbody>
    <tr>
      <td style="font-weight:bold; text-align:left; white-space:nowrap;">Birthdays</td>
      <td style="font-weight:bold; text-align:center; white-space:nowrap;">Status</td>
    </tr>
    <tr *ngFor="let template of templates">
      <td>{{ template }}</td>
      <td></td>
    </tr>
  </tbody>
</table>

email-list.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'

@Component({
  selector: 'app-email-list',
  templateUrl: './email-list.component.html',
  styleUrls: ['./email-list.component.css']
})
export class EmailListComponent implements OnInit {
  templates = ['Birthday 5-10', 'ResponsiveBDay', 'Testing', 'Birthday2', 'PresidentsDay2018', 'Christmas2017', 'Thanksgiving2017','Columbus Day', 'Labor Day', 'Father Day 2017'];

  constructor(
    private route: ActivatedRoute,
    private router: Router
  ) { }

  ngOnInit() {}

}

empty.component.html

<!-- This intentionally blank -->
<p>Empty is working</p>

empty.component.ts import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-empty',
  templateUrl: './empty.component.html',
  styleUrls: ['./empty.component.css']
})
export class EmptyComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

Solution

  • I am not sure of the reason why, but I could never actually get this to work using the children attribute in my route table. I was able to get it working finally when I moved the children to the same level as the parent. I am not sure if this is new to Angular 6 or what.

    Here is the final result:

    updated app-routing.module.ts

    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    
    import { CampaignSettingsComponent } from './campaign-settings/campaign-settings.component';
    import { EmailListComponent } from './email-list/email-list.component';
    import { EmailPreviewComponent } from './email-preview/email-preview.component';
    import { EmptyComponent } from './empty/empty.component';
    
    const routes: Routes = [
      { 
        path: '', 
        pathMatch: 'full',
        component: EmailListComponent, 
        outlet: 'list_panel',
      },
      { 
        path: '',
        pathMatch: 'full',
        component: EmptyComponent,
        outlet: 'action_panel'
      },
      { 
        path: '',
        pathMatch: 'full',
        component: EmptyComponent,
        outlet: 'detail_panel'
      },
    ];
    
    @NgModule({
      imports: [
        RouterModule.forRoot(routes, 
          {enableTracing: false} // for debug only
        )
      ],
      exports: [ 
        RouterModule
      ]
    })
    
    export class AppRoutingModule { }