0

I have a scenario where i have 3 tabs in my web page, where in tab content area three different components loads on activation of each tab(say components 'ABC','PQR','XYZ'). In the main page in which tabs are present i have to show some header data related to the tab content loaded in the tab. Suppose if tab BAC is loaded, i have to show some message sent from ABCcomponent, likewise for all three components.

I tried with single component but my event listner is not working.

Main Tabs Page(Parent Component): HTML File tabs.component.html:

 <h1>{{headerMessage}}</h1>

<my-tabs [items]="tabItems">
    <router-outlet (tabHeaderTextEvent)="receiveHeaderText($event)"></router-outlet>
</my-tabs>

tabs.component.ts:

import { Component, OnInit } from '@angular/core';
import { TabItem } from '@MYCOMPONENTS/tabs';

@Component({
  selector: 'MYPAGE-tabs',
  templateUrl: './tabs.component.html',
  styleUrls: ['./tabs.component.scss']
})
export class TabsComponent implements OnInit {
  public headerMessage: String;
  public tabItems: TabItem[] = [];

  constructor(private authService: AuthService) {
    this.tabItems = [{
      routerPath: 'abc',
      label: 'ABC_LABEL',
    }, {
      routerPath: 'PQR',
      label: 'PQR_LABEL',
      disabled: true
    },
    {
      routerPath: 'XYZ',
      label: 'XYZ_LABEL',
      disabled: true
    }];
  }

  receiveHeaderText($event) {
    console.log('***********************************');
    console.log($event);
    this.headerMessage = $event;
  }
}

Child.component.ts (from where i wish to send data):

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

@Component({
    selector: 'someSelector',
  templateUrl: './sometemplate.component.html'
})
export class Child implements OnInit {
  @Output() tabHeaderTextEvent = new EventEmitter<string>();

  constructor() {
    this.tabHeaderTextEvent.emit('hello from overview component');
  }
}

Likewise i have two more components those are emitting tabHeaderTextEventevent on its constructor call. But i my listener function in my tab component is never getting called. Can anyone guide me where i am going wrong ? OR Any better approach to achieve the same. Thanks in advance.

Anonymous
  • 1,726
  • 4
  • 22
  • 47
  • 2
    The short answer is that you can't pass data via bindings on the `router-outlet`. https://stackoverflow.com/questions/41451375/passing-data-into-router-outlet-child-components-angular-2 While this question relates to input data, the same is true for output data. You'll likely need a shared service to get around this – Vlad274 Jul 19 '18 at 14:37

1 Answers1

1

You can try using Injector.

import { Injector } from '@angular/core';
import { MyPageComponent } from "./mypage.component";
export class Child implements OnInit
    constructor(private injector: Injector) {
        let parentComponent = this.injector.get(MyPageComponent);
        parentComponent.receiveHeaderText('String');
    }
}
Rahul Sharma
  • 9,534
  • 1
  • 15
  • 37
  • 1
    I would advise against this. – Roberto Zvjerković Jul 19 '18 at 14:57
  • @ritaj, can you please explain if there are any bad consequences of injecting a paent component into child and accessing the properties from child. If this is bad practice , then why is it so? – Anonymous Jul 20 '18 at 10:55
  • @Rahul Sharma, Thanks. While googling i did not found this way of data sharing between parent and child (may not be recommended) , but this solution worked for my scenario. Your solution is like we are accessing parent component properties into child component. Let me see if some better solution comes, if not i will accept your answer currently i have up voted it . – Anonymous Jul 20 '18 at 11:00