Reputation: 21116
I have the following structure:
<app>
<test-a></test-a>
<test-b></test-b>
</app>
@Component({
selector: 'app',
templateUrl: './app.component.html',
})
export class AppComponent {
}
@Component({
selector: 'test-a',
templateUrl: './testa.component.html',
})
export class TestAComponent {
}
@Component({
selector: 'test-b',
templateUrl: './testb.component.html',
})
export class TestBComponent {
}
Test B
contains selectable items. When one is selected, i'd like to tell Test A that the item was selected...
I think there are 2 options i'm aware of that can achieve this.
App
to store the selected item. Modify that selected item in Test B
and then allow Test A
to react... but it makes an ugly tight coupling between the Test A
and Test B
components... and the parent App
component. I don't like that idea. // Model required for my own class
export class KeyValuePair<T>
{
public key: string;
public value: T;
construct(key: string, value: T) {
this.key = key;
this.value = value;
}
}
// How my implementation might look (wip)
import { Observable, of } from "rxjs";
import { KeyValuePair } from "../models/keyvaluepair";
import { Injectable } from "@angular/core";
@Injectable({
providedIn: 'root',
})
export class EventService<T>
{
protected subscriptions: KeyValuePair<Observable<T>>[];
public Broadcast(key: string, value: any)
{
var observable = new Observable<T>();
observable.subscribe((a) =>
{
return of(value);
});
this.subscriptions.push(
new KeyValuePair<Observable<T>>(
key,
observable
)
);
}
public Subscribe(key: string): Observable<T>
{
var observable = this.subscriptions.find((sub) => {
return sub.key == key;
});
return observable.value;
}
}
// How you might create a event
this.testEventService.Broadcast("itemSelected", item);
// How it might be used
this.testEventService.Subscribe("itemSelected").subscribe((item) => {
this.changeItem(item);
});
However, surely i shouldn't have to write this stuff..? In angularjs and jquery there was a $broadcast and $on kind of thing that made life so simple... what am i missing here? Is there an easier way in angular 6 and typescript?
Edit:
I have made a service people can use, please tell me if it sucks: https://jsfiddle.net/jimmyt1988/oy7ud8L3/
Upvotes: 2
Views: 12482
Reputation: 1880
you can use Subject
export class EventService<T> {
protected _eventSubject = new Subject();
public events = this._eventSubject.asObservable();
dispathEvent(event) {
this._eventSubject.next(event);
}
}
Upvotes: 4