Reputation: 965
I have a search component containing a logo, a searchbar and a routeroutlet. The execution of a search navigates to the resultlist, which is the pseudo html outlined here:
<search>
<logo></logo>
<searchbar></searchbar>
<result-list></result-list>
</search>
I like to style logo and searchbar differently on the results page so I tried to select the logo with :host >>> logo
and the /deep/
alternative from the result-list
component. That doesn't work. Is there a way to select siblings?
Here a small plnkr to demonstrate the problem. http://plnkr.co/edit/Q0CLjcsftbqe0kHKrKks?p=preview Here I would like to style from resultlist
the logo
and the searchbar
to be black.
Upvotes: 6
Views: 2009
Reputation: 1
You can use services for communication between components and ngClass for dynamic styling.
notification.service.ts
import {Injectable, EventEmitter} from '@angular/core';
@Injectable()
export class NotificationService {
private static _emitters: { [ID: string]: EventEmitter<any> } = {};
static get(ID: string): EventEmitter<any> {
if (!this._emitters[ID]) {
this._emitters[ID] = new EventEmitter();
}
return this._emitters[ID];
}
}
When sibling component run send a message.
bar.component.ts
import { NotificationService } from 'notification.service';
....
ngOnInit() {
NotificationService.get('barcomponent').emit(true);
}
ngOnDestroy() {
NotificationService.get('barcomponent').emit(false);
}
...
Listen to incoming messages from your component.
foo.component.ts
import { NotificationService } from 'notification.service';
....
ngOnInit() {
NotificationService.get('barcomponent').subscribe(value => {
this.activateStyle = value;
});
}
....
You can apply any class via ngClass
foo.component.html
....
<div [ngClass]="{'my-css-class':activateStyle}">
...
</div>
....
Upvotes: 0
Reputation: 965
A Similar solution to the one from Jens Habegger using :host-context(myCssClass)
and a conditional. The style needs to be added to the logo
and the searchbar
component.
<search>
<logo [class.myCssClass]="isSearchResultList"></logo>
<searchbar [class.myCssClass]="isSearchResultList"></searchbar>
<result-list></result-list>
</search>
:host-context(.myCssClass) {
color: black;
}
Upvotes: 2
Reputation: 5456
What you are attempting is basically sharing global application state isSearchResultList: boolean
across multiple components.
The obvious naive solution would be to hold the state at the respective shared parent component, and set it based on the current router-outlet.
<search>
<logo [isSearchResultList]="isSearchResultList"></logo>
<searchbar [isSearchResultList]="isSearchResultList"></searchbar>
<result-list></result-list>
</search>
Upvotes: 1