2

I have a header component and a sidebar component as child component of Main component as follows.

main component

@Component({
    selector: 'my-app',
  template: `
    <body>    
      <app-header></app-header>
      <app-sidebar></app-sidebar>
      <main class="mdl-layout__content mdl-color--grey-100">         
         <auth-router-outlet></auth-router-outlet>        
      </main>
    </div>         
  </body>

    `,
    directives: [ROUTER_DIRECTIVES, SidebarComponent, HeaderComponent, MDL, AuthRouterOutlet,SimpleNotificationsComponent],
    providers: [AUTH_PROVIDERS,NotificationsService]
})

export class AppComponent {}

The header component has a child component. I want to destroy this child component when the user click on any of the sidebar links. Currently the child component becomes part of the header once data is rendered and breaks the layout.

HeaderComponent

@Component({
    selector: 'app-header',
     directives: [AptSearchComponent],
    template: `
            <div class="mdl-textfield__expandable-holder">
              <input class="mdl-textfield__input" type="text" id="search" (keyup.enter)="Search($event)">
            </div>       
     <aptsearch *ngIf="apartment" [model]="apartment"></aptsearch>    
    `,
})

export class HeaderComponent {

  public apartment: string;

    constructor(private apartmentService: ApartmentService,private router: Router,private sharedService: SharedService) { 
       this.apartmentService=apartmentService;
       this.sharedService=sharedService;
     }

     Search(event){  
       this.apartment = event.target.value;
       this.router.navigate(['AptSearch']);     
     }
}

child component of the header component, which needs to be destroyed when user click on any links from the sidebar.

@Component({
    selector: 'aptsearch',  
  template: `    
     <div *ngFor="#aptdetails of aptDetails">
                <h2 class="mdl-card__title-text">{{aptdetails.aptID}}</h2>
              </div>

    </div>         
    `,
    directives: [ROUTER_DIRECTIVES]
})

export class AptSearchComponent implements OnInit {
    @Input() model:string;

    aptDetails: any;

    constructor(private apartmentService: ApartmentService, private sharedService: SharedService,private zone:NgZone) {
    this.apartmentService = apartmentService;        
    }


    ngOnInit(){}

    ngOnChanges(changes: any) {
    console.log('Inside the Search Component from parent -->' +this.model);
    this.apartmentService.searchApt2(this.model).subscribe(res => {this.aptDetails = res});
    }    
}

How can this be achieved ?

user2180794
  • 1,425
  • 7
  • 27
  • 50
  • Did you try auxiliary routes ? Your links could trigger the appearance or the hiding of the sidebar in a global way. – Ghetolay Nov 07 '16 at 11:20

2 Answers2

1

Use *ngIf

and set showChild to false to get the element removed from the DOM.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
0

There's no straightforward way to connect two sibling components (header and sidebar, in your case).

One option would be to have the sidebar component emit an event (EventEmitter) that the app component (a) subscribes to and (b) then sets a property in the header component.

Another option, my preferred one, would be to have an observable in your ApartmentService or another service. Something like this:

In ApartmentService:

apartmentSearch: new BehaviorSubject<string>();

search(query: string) {
    this.apartmentSearch.next(query);
}

In Sidebar when something is clicked, call search with null:

somethingClicked() {
    this.apartmentService.search(null);
}

In Header:

ngOnInit() {
    this.subscription = this.apartmentService.apartmentSearch.subscribe(x => this.apartment = x);
}

ngOnDestroy() {
    this.subscription.unsubscribe();        
}

Search(event) {
    this.apartmentService.search(event.target.value);
}

I hope this helps.

Carlos Mermingas
  • 3,822
  • 2
  • 21
  • 40
  • There are multiple components in sidebar, so this won't work. The best case would be to set it to null in the child compoennt itself, when the user navigates out. I thought of ngOnDestroy() .. but its not called in the child. – user2180794 Nov 06 '16 at 20:24
  • You req is "when the user click on any of the sidebar links"... You can call `somethingClicked()` when these links are clicked. I am not sure how this interacts with the multiple components in the sidebar. – Carlos Mermingas Nov 06 '16 at 21:48
  • There are routerlinks in the sidebar, which navigate to respective components. It's not elegant if I have to do it at every component. – user2180794 Nov 06 '16 at 21:52
  • I agree it's not elegant. You don't have to do it in every component, though. Just in the links in the sidebar. Your req is that when something happens in the sidebar, you want to hide a section in sibling component. Either the sidebar emits an event that the parent component listens to and passes an action down to another component, or the sidebar communicates a change in state to a service that the sibling component consumes. – Carlos Mermingas Nov 06 '16 at 23:08
  • I am trying to make this work. I think this is what you are referring too as well. http://stackoverflow.com/questions/35685801/angular-2-event-catching-between-sibling-components – user2180794 Nov 07 '16 at 09:35