0

I am working on an Angular 4 application where I have one left panel and one right panel.

Apart from those panels I have 2 other components.

The left panel component contains buttons and the right panel component is currently empty.

What I want to do is when I click (for example), button 1 on the left panel component it loads a component inside the right panel component and so on.

It's the same as routing but I'm already using routing on my app.component for the top main menu so that's taken.

How do I go about doing this?

  • The suggested solutions seem pretty involved. If the components you're loading when pressing the buttons are NOT dynamically generated, it seems like overkill to use dynamic component loading. What do you mean by "I'm already using routing on my app.component for the top main menu so that's taken"? The router offers a lot of flexibility to display "secondary routes" (you could use child routes, for instance, or a named router outlet) – AngularChef Nov 01 '17 at 11:14

2 Answers2

0

you may want to use a service to handle this.

Providing the service from the common parent component and injecting it inside the two components you will have a common poi for communication. at this point you can subscribe to some event in the right panel component of the service and raise it from the left calling a specific method:

this is an example of using events inside services

FrontTheMachine
  • 526
  • 3
  • 14
-1

Here is a rough example of this kind of implementation.

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
    selector: '[buttonView]'
})
export class ButtonViewDirective {

    constructor(public viewContainerRef: ViewContainerRef) {}

}

import { ComponentFactoryResolver } from '@angular/core';
import { OneComponent,  TwoComponent } from './components';

@Component({
    selector: 'right-panel',
    encapsulation: ViewEncapsulation.Emulated,
    template: `
        <div>
            <ul>
                <li *ngFor="let button of buttons">
                    <button (click)="onButtonClick(button)">{{button.name}}</button>
                </li>
            </ul>
        </div>
        <div>
            <ng-template buttonView></ng-template>
        </div>
    `
})
class RightPanelComponent {

    public buttons: any = [
        {
            name: 'Button 1',
            component: OneComponent
        },
        {
            name: 'Button 2',
            component: TwoComponent
        }
    ]

    @ViewChild(ButtonViewDirective)
    public buttonViewContent: ButtonViewDirective;

    constructor(
        protected _cmpFactoryResolver: ComponentFactoryResolver,
    ) {}

    public onButtonClick(button: any): void {
        this._createComponent(button);
    }

    private _createComponent(button: any): void {
        if (button === null) {
            return;
        }
        setTimeout(() => {
            const cmpFactory = this._cmpFactoryResolver.resolveComponentFactory(button.component);
            const viewContainerRef = this.buttonViewContent.viewContainerRef;
            viewContainerRef.clear();
            viewContainerRef.createComponent(cmpFactory);
        });
    }
}

The ButtonViewDirective is used like helper in our RightPanelComponent just to make much easier to bootstrap custom components: OneComponent, TwoComponent

The RightPanelComponent combines both panels the right and left one for this example. If you want to have them split then the right panel will have the logic of rendering and bootstrapping custom components and the left panel will have the logic of rendering button and trigger changes to the right side components. Communication between Right and Left can be made with an intermediate Service or some kind of events, observables implementation.

Here are some examples of implementation in the official angular doc. https://angular.io/guide/dynamic-component-loader

LkPark
  • 566
  • 4
  • 12