英文:
Angular Subject: share only with some of the observers
问题
以下是您要翻译的内容:
给定一个基本类型
export interface Item {
id: string;
}
我定义了一个名为BackupClient
的类,其中包含一个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);
}
}
通过BackupService
,组件ItemComponent
可以订阅我的BackupClient
,并在BackupClient
共享新的Item
时更新其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;
}
在我的应用程序中,现在有许多ItemComponent
实例。通过在观察者内部检查id
,我可以避免在只有一个item
更改时更新所有组件。
我希望通过使用某种类型的Subject
或多播设计来改进这一点,仅与具有特定id
的ItemComponent
的观察者共享。也就是说,所有组件仍然订阅一个Subject
,但共享仅限于具有给定id
的那些ItemComponent
。
英文:
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 ItemComponent
s with given id
.
答案1
得分: 1
如果我理解你的意思正确,你希望订阅者只在发出的事件是特定id
的项目时才接收这些事件。
在这种情况下,你可以修改你的subscribe()
方法,以接受id
并过滤掉来自其他项目的事件:
public subscribe(id: string, observer?: Partial<Observer<Item>>): Subscription {
return this.subject.pipe(
filter(item => item.id === id)
).subscribe(observer);
}
this.backupService.client.subscribe(this.id, ...);
上述代码在构造函数中不起作用,因为@Input() id
直到至少ngOnInit()
生命周期钩子被调用之前都是未定义的。
你的BackupClient
类的subscribe
方法可能会引入内存泄漏问题。每当消费者调用.subscribe()
时,你都会创建一个订阅,但似乎没有办法取消订阅它们。你可以考虑返回一个Observable,让消费者订阅,然后由消费者负责取消订阅:
public item(id: string) {
return this.subject.pipe(
filter(item => item.id === id)
);
}
然后在你的组件中使用:
this.backupService.client.item(this.id).subscribe(...);
英文:
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:
public subscribe(id: string, observer?: Partial<Observer<Item>>): Subscription {
return this.subject.pipe(
filter(item => item.id === id)
).subscribe(observer);
}
this.backupService.client.subscribe(this.id, ...);
The above code won't work in the constructor, because the @Input() id
will be undefined until at least the ngOnInit()
lifecycle hook.
The subscribe
method of your BackupClient
class 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:
public item(id: string) {
return this.subject.pipe(
filter(item => item.id === id)
);
}
Then in your component:
this.backupService.client.item(this.id).subscribe(...);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论