Given a basic type
export interface Item {
id: string;
}
I define a class BackupClient with a Subject:
export class BackupClient {
private subject = new Subject<Item>();
private share(item: Item): void {
this.subject.next(item);
}
public subscribe(observer?: Partial<Observer<Item>>): Subscription {
return this.subject.subscribe(observer);
}
}
Via the BackupService a component ItemComponent may subscribe to my BackupClient and update its item whenever BackupClient shares a new item.
import { BackupClient } from './backup.client';
import { Injectable } from '@angular/core';
@Injectable()
export class BackupService {
constructor() {}
public client = new BackupClient();
}
import { BackupService } from '../backup.service';
import { Component, Input } from '@angular/core';
import { Item } from '../item';
@Component({
selector: 'app-item',
templateUrl: './item.component.html',
styleUrls: ['./item.component.css'],
})
export class ItemComponent {
constructor(private backupService: BackupService) {
this.backupService.client.subscribe({
next: (item) => {
if (this.id === item.id) {
this.item = item;
}
},
});
}
@Input() id?: string | null;
protected item?: Item | null;
}
In may app I now have many ItemComponent instances. By checking the id inside my observer I avoid an update of all components if only one item changes.
I would like to improve this by using some kind of Subject or multicasting design that only shares with observers of some id. That is, still all components subscribe to one Subject, but sharing is constrained to only those ItemComponents with given id.
If I'm understanding you correctly, you want subscribers to only receive emissions if the emission is for an item with a specific
id.In that case, you could modify your
subscribe()method to take in the id and filter out emissions from other items:The above code won't work in the constructor, because the
@Input() idwill be undefined until at least thengOnInit()lifecycle hook.The
subscribemethod of yourBackupClientclass is probably introducing memory leaks. Each time a consumer calls.subscribe(), you create a subscription, but it doesn't appear that you have a way to ever unsubscribe from them. You may want to consider returning an Observable that consumers subscribe to, then the consumer can be responsible of unsubscribing:Then in your component: