Search code examples
angularurl-routingangular-template

Define a routed element with multiple templates


I'm trying to create a routed component which has multiple template entry points and I don't know if this is possible in Angular. I'll elaborate a little.

In Angular we can create nested elements which contain templateRefs to inject some part of the child component into the parent component (for example, the Menu from child in the following image).

enter image description here

The main problem is that I don't know how I can do this with routed components. I want that the navigation on parent makes the navigation on the ng-content (which now will be a <router-outlet>) but also updates the Menu based on some template I define in the child component. Is this possible? How can I start?


Solution

  • Yes, if you use child component by using the selector in parent component you can this easily. But since you are using the routed component and are using the <router-outlet> for rendering the child component.

    You need to pass the data from child component to the parent. For doing this you can use the service having the data to be rendered in the parent component in the section where the data is decided in the child component.

    For this you can create one service suppose data.service.ts:

    @Injectable({
      providedIn: 'root'
    })
    export class DatService {
      dataToRendered$: BehaviorSubject<boolean> = new BehaviorSubject(false);
      constructor(){}
      setDataToRender(data:any){
       this.dataToRender.next(data);
      }
    }
    

    So in parent component you can use the instance of this service and keep the variable dataToRender subscribed. Whenever the data gets changed you would get the updated data.

    this.dataService.dataToRender.subscribe((data)={ console.log(data)})
    

    And in the child component you can just call the method setDataToRender() method to update the data in parent component, by using the instance of the DataService. The sample code is as shown:

    this.dataService.setDataToRender({name:'Demo'});
    

    Edited:

    If you have your template defined in the html of child component. you can get it in .ts using @ViewChild('template') template: TemplateRef; Your html file of child component should have:

    <ng-template #template></ng-template>
    

    and call setDataToRender(this.template).

    In parent component get this data and define <ng-container #vc></ng-container> in html. Now Add the following in .ts

      @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
    
      this.dataService.dataToRender.subscribe((data)={ 
       this.vc.insert(data);
       })