简体   繁体   中英

How to change the header on parent component according to route

Using Angular 7.x, I want to change my parent header component accordingly to the child routes and if they're activated or not. So in my case

AppComponent   
     Feature Module <= detect changes here    
          Child Components of feature module

So my routing is very simple, the app-routing.module just contains the loading of the feature module with loadChildren, nothing fancy here.

Then this feature module contains the routes for the child components. There is one parentComponent, we call it ParentComponent which contains the router-outlet. There is also some headers that I want to change accordingly to the childs.

SO i have two child components: create , and ' :id' (detail page). When I trigger these routes I need the parent component to just change their text content accordingly. So for example when the create page is triggered I want to add the header: "Create new item", and for the :id page I want to show "Detail page".

Now, I have figured out I need to subscribe to the router events or on the activatedRoute (or snapshot). I'm at a loss here so I don't really know what to do here.

My parent component looks like this now:

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

@Component({
  selector: 'parent-component',
  templateUrl: './parent.component.html',
})
export class ParentComponent implements OnInit {
  title = 'Parent Title';
  // Check if it is possible to change the title according to the route
  subtitle = 'Parent subtitle';

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

  ngOnInit(): void {
    this.route.url.subscribe(data => {
      if (this.route.snapshot.firstChild) {
        console.log('yes', this.route.snapshot.firstChild);
        // Change header with a if/else or switch case here
      } else {
        // Display standard text 
        console.log('no');
      }
    });
  }
}

this is the output of the console.logs, notice in my real application the parent is named 'timesheets'.

在此处输入图片说明

Is there maybe another solution for this? Maybe a service, but all of the information is basically in the route already, so I'm trying to figure out if this is the way to go for my problem.

You can listen NavigationEnd events in ParentComponent or (I think) even better you can use a title service.


Solution 1:

In ParentComponent

import {NavigationEnd, Router} from '@angular/router';
import {filter} from 'rxjs/operators';
...



constructor(private router: Router, private readonly route: ActivatedRoute) {
    this.subscribeRouterEvents();

}

subscribeRouterEvents = () => {
    this.router.events.pipe(
      filter(e => e instanceof NavigationEnd)
    ).subscribe(() => {

       this.title = this.route.snapshot.data['title'];
       // Assuming your route is like:
       // {path: 'path', component: MyComponent, data: { title: 'Page Title'}}
    });

Solution 2:

Using TitleService . Create a service that holds the page title, subscribe to title from ParentComponent and send new title to service from ChildComponent .

TitleService

@Injectable({
  providedIn: 'root'
})
export class TitleService {

  private defaultTitle = 'Page Title';
  private titleSubject: BehaviorSubject<string> = new BehaviorSubject(this.defaultTitle);
  public title: Observable<string>;

  constructor(private titleService: Title) {
    this.title = this.titleSubject.asObservable();
  }

  public setTitle(title: string) {
    this.titleSubject.next(title);
  }
}

ParentComponent

pageTitle = 'Page Title';
constructor(private titleService: TitleService) {}

ngOnInit(){
  this.titleService.title.subscribe(value => this.pageTitle = value);
}

ChildComponent

pageTitle = 'Child Component Title';
constructor(private titleService: TitleService) {}

ngOnInit(){
  this.titleService.setTitle(this.pageTitle);
}

You can try setting the title for a child as part of route like this.

const routes: Routes =[
  {
    path: 'create',
    component: SomeComponent,
    data : {header_title : 'some title'}
  },
];

ngOnInit() {
   this.title = this.route.data.subscribe(x => console.log(x));
}

and get the title in the child component and set that as header title using a service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM