1
votes

I have a parent component where few links (using routes) are available to load the child components. The child component should be loaded within the parent component. Also there are few filters (check boxes) available in the parent component which has to applied during the load of any child components.

Sample code

<div class="parent">
    <div class = "logo"/>
    <div class = "headercontent">........................</div>
    <div class = "links"><a>**News**</a><a>**Vidoes**</a><a>**Audio**</a></div>
    <div class = "filters">
        <input type="checkbox">Filter 1 </input>
        <input type="checkbox">Filter 2 </input>
        <input type="checkbox">Filter 3 </input>
    </div>
    <div class = "fewmorecontent">........................</div>

    **<router-outlet></router-outlet>**

    <div class = "fewmorecontent">........................</div>
    <div class = "fewmorecontent">........................</div>
</div>

I am able to load the News HTML Component Or Video HTML Component or Audio HTML component within the router-outlet by clicking on the links. I was able to achieve this by specifying child routes.

But the child components has to be filtered based on the filters chosen in the parent page. The filters are common for all the child components.

Note : Only one child component will be loaded at a time and on selection of other component it has to overwrite the earlier child component content within the router-outlet

How do i pass the filter values in the parent page to the child components.

Couple of things I tried

  1. @Input decorator , but was unable to set in the router outlet to be passed.
  2. Along with @Input ,tried giving a common selector for all components and added the selector (< app-child >) within router outlet but it threw an error as each component requires unique selector.
  3. I also tried creating a service and passing it, but was not able to succeed.

Hope I was clear in explaining the issue.

Any guidelines or solution to resolve this?

2

2 Answers

1
votes

You're going to want to make a service. like:

@Injectable()
export class myService(){
  private dataObj$ = new Subject();

  updateData(event: any) {
    this.dataObj$.next(event);
  }

  getData() {
    return this.dataObj$;
  }
}

then in your child component you set up a subscriber for the getData function and in the filter component use the updateData function and the child component will listen for those changes

EDIT: here is a working example: https://stackblitz.com/edit/angular-aq9wx9

0
votes

As for my experience, a shared service will suit your requirements. I will share an example code snippet here.

//SharedService

@Injectable()
export class SharedService {

  private message = new BehaviorSubject('First Message');
  sharedMessage = this.message.asObservable();

  constructor() { }

  nextMessage(message: string) {
    this.message.next(message)
  } 
}

//Parent Component export class ParentComponent implements OnInit {

  message:string;

  constructor(private sharedService: SharedService) { }

  ngOnInit() {
    this.sharedService.sharedMessage.subscribe(message => this.message = message)
  }
}

//ParentHTML

Message from Service : {{message}}

//SiblingComponent

export class SiblingComponent implements OnInit {

  message:string;

  constructor(private sharedService: SharedService) { }

  ngOnInit() {
    this.sharedService.sharedMessage.subscribe(message => this.message = message)
  }

  newMessage() {
    this.sharedService.nextMessage("Second Message")
  }
}

//SiblingHTML

<h1>Message from Service : {{message}}<h1>
<button (click)="newMessage()">Change Message</button>

A more detailed doc can be found here.