There are several ways to accomplish sibling component communication:
1. Service
The first option is to have a service with a public observable property and inject it into the components.
@Injectable()
export class ToggleService {
private toggle = new Subject<boolean>();
public $toggle = this.toggle.asObservable();
constructor() { }
setToggle(val: boolean){
this.toggle.next(val);
}
}
From there your components would be
TogglerComponent
export class TogglerComponent {
constructor(toggleService: ToggleService){}
visible: boolean = false;
toggleBox(): void {
this.visible = !this.visible;
this.toggleService.setToggle(this.visible);
}
}
BoxComponent
export class BoxComponent implements OnInit {
constructor(toggleService: TogglerService){
}
ngOnInit(){
this.toggleService.$toggle.subscribe(val => {
// Do Something
});
}
}
Note: With this approach you need to be careful with the DI scope, as it is necessary that both components share the same instance of the service. So your provider should be either in either the parent component or a shared or parent module.
2. Parent Property
The second alternative is to have a property in the parent and bind it to both components.
Your ParentComponent
would be something ilke
export class ParentComponent implements OnInit {
public toggle: boolean;
constructor() { }
ngOnInit() {
}
changeToggle(val){
this.toggle = val;
}
}
And your template would just bind that function and property
<toggler (toggle)="changeToggle(toggle)"/>
<box [toggle]="toggle"/>
3. BindingLess Solution (Not Recommended)
Based on your comment there is another alternative, using ViewChild
, which would look something like:
export class ParentComponent implements AfterViewInit {
@ViewChild(TogglerComponent)
togglerComponent: TogglerComponent;
@ViewChild(BoxComponent)
boxComponent: BoxComponent
constructor() { }
ngAfterViewInit() {
this.togglerComponent.toggle
.subscribe(val => this.boxComponent.toggle = val)
}
}
For further reference you could check: https://angular.io/guide/component-interaction