I got a basic app: a top bar and a general area: (this is a simplified HTML version, from app.component.html)
<header>
<app-top-bar >
</app-top-bar>
</header>
<main>
<div >
<router-outlet></router-outlet>
</div>
</main>
now: in the app-top-bar I got an INPUT used as a general search - and the search will be applied on whatever component will come in real time inside router-outlet. I need, therefore, to let the child component "know" (via calling a method on it or any other mechanism) that a search term has been entered.
Now I know how a parent an communicate with a child (@input, @ViewChild...) but how do I do it in this scenario - communicating with a child that keeps changing depending on user navigation?
CodePudding user response:
You could create a ServiceService
on root level providing a search(...)
method and a searchChanges()
method returning an observable. Then simply inject the service into components that support the global search listen for search changes.
search.service.ts
@Inject({ providedIn: 'root' })
export class SearchService {
private readonly searchChanges$ = new Subject<string>();
search(text: string): void {
this.searchChanges$.next(text);
}
searchChanges(): Observable<string> {
return this.searchChanges$.asObservable();
}
}
top-bar.component.ts
@Component({
selector: 'app-top-bar',
...
})
export class TopBarComponent {
constructor(private searchService: SearchService) {
}
onSearch(text: string): void {
this.searchService.search(text);
}
}
other.component.ts
@Component({
selector: 'app-other',
...
})
export class OtherComponent implements OnInit {
constructor(private searchService: SearchService) {
}
ngOnInit(): void {
this.searchService.searchChanges().subscribe(text => {
// Handle search here
});
}
}