Angular 2 Header component Title change dynamically according to the state

Saiyaff Farouk picture Saiyaff Farouk · Nov 24, 2016 · Viewed 7.2k times · Source

I have a design using angular 2 where header component, navigation bar component and body component where all other components load. As the picture shows below

  1. Header
  2. Navigation
  3. Where other components load (this section might have nested components/ children components)

Angular components

So here basically, In the header component, I want to show the current state. And in the bottom of the current state, I want to show the previous state of the user.

Issues: To implement this I used the component interaction technique in angular.

  • once the app is reloaded it shows the default value for current and
    the back states.

  • In a scenario like where user straightly landing to the particular page which is a child component in the body also, it shows the default value for the current and the back state.

Since angular is following the component architecture I want a better way to implement this feature.

If I am straightly coming to a child component in section-3 in the picture my header component should get the title/current state according to the specific page in the header component.

My solution for this was in each component when ngOnInit I pass the current state value. Also I parse the previous state value. Therefore the header component shows it as it is since the service is written using the technique in this link - https://angular.io/docs/ts/latest/cookbook/component-communication.html

But there are some instances I get the data from the server and have to update the header current state. There I see that is not showing at all.

Need help with a good solution.

PS - Since this mechanism is in different kinda files and it's a bit complex I am helpless to update a code template

Answer

Aravind picture Aravind · Mar 11, 2017

Though it looks to be a simple one, but it can be achieved using child component and Input, Output variables.

Child Component for displaying the content from the service

@Component({
  selector: 'title',
  template: `
    <div> {{title}}</div> 
  `,
})
export class TitleComponent implements ngOnChanges{

  @Input() title:string="";
  @Output() titleChanged:EventEmitter<string>=new EventEmitter<string>();
  constructor(){
  //service call goes here
  }
  ngOnChanges(){
  console.log(this.val);
  this.titleChanged.emit(this.title);
  } 

}

Parent component will be as

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <title (titleChanged)="changedTitle($event)" [title]="title"></title>
    </div>
  `,
})
export class App {
  name:string; 
  title:string="some title";
  val:string;
  constructor() {
    this.val="";

  }

   changedTitle(va;){
   this.title="val"
    console.log(val);

  }
}

Explanation:

  1. When service call is made and the title value gets changed.
  2. On change of the input property the ngOnChanges will be triggered automatically.
  3. The titleChanged is Output() variable and emits a value when ever ngOnChanges is executed.
  4. When the titleChanged is triggered, the associated method in the changedTitle() will be executed.

LIVE DEMO

Note: In order to show this is working I have used an text box and assigning it to the div element, you can modify this in the constructor of the routed component.