在 Angular 个组件之间通过服务共享 map/object/array 中的数据的最佳做法是什么
What is the best practice to share data in map/object/array by service among Angular components
我正在学习angular。当谈到使用服务进行数据共享时,许多人建议我们应该使用Subject like BehaviorSubject。
但是我们应该一直这样做吗?
@Injectable({
providedIn: 'root'
})
export class DataService {
private imageUrls = new Map<number, string>();
public imageUrlsSubject = new BehaviorSubject(this.imageUrls);
public size(): number {
return this.imageUrls.size;
}
public set(id: number, url: string): void {
this.imageUrls.set(id, url);
this.imageUrlsSubject.next(this.imageUrls);
}
public get(id: number): string {
return this.imageUrls.get(id);
}
public has(id: number): boolean {
return this.imageUrls.has(id);
}
}
我按照这种做法写了一个这样的服务。这让我想知道:我们真的需要 Subject 吗?在另一个组件只需要使用 DOM 中的地图的情况下,我可以 摆脱 imageUrlsSubject 吗?
<img
*ngIf="dataService.has(row.id)"
[src]="dataService.get(row.id).url">
在另一个组件中,我可能只需要调用 dogDataService.set 来更新地图。
this.dataService.set(id, url);
如果去掉 Subject,会不会带来一些潜在的弊端?
谢谢!
你只是在内部使用你的 BehaviorSubject,但你的 getter 并不依赖它。您当前的服务与其消费者完全同步,"yes",您现在编程的方式 imageUrlsSubject
并不是真正必要的。
使用 Subject 的真正优势在于您可以将其作为 Observable 提供给其他地方!人们不再只能访问 imageUrls
的当前值,而是可以访问 imageUrls 的当前值和所有未来值!他们被赋予了流而不是快照。
然后您有 3 个设计选项:
- 总是return一个Observable。如果人们想要快照,他们必须通过管道传输
take(1)
。
- 始终 return 一个 Observable,但添加一个 shorthand 函数
snap
,return 是当前值。
- 总是 return 一个快照(就像它当前在您的代码中所做的那样)并添加一个
watch
函数,该函数 return 是一个 Observable。
我会更进一步说你不应该保留一个单独的 imageUrls
属性 而应该依赖 imageUrlsSubject.value
(仅用于 BehaviorSubjects)。我只是推荐这个,这样你 A) 不太可能忘记 subject.next(newValue)
当你改变你的价值 B) 再次提醒你你应该使用你的主题;p
这里是保持 get
默认同步行为并添加异步 watch
.
的改编示例
@Injectable({
providedIn: 'root'
})
export class DataService {
public imageUrlsSubject = new BehaviorSubject(new Map<number, string>());
public size(): number {
return this.imageUrlsSubject.value.size;
}
public set(id: number, url: string): void {
this.imageUrlsSubject.value.set(id,url);
this.imageUrlsSubject.next(this.imageUrlsSubject.value);
}
public get(id: number): string {
return this.imageUrlsSubject.value.get(id);
}
public has(id: number): boolean {
return this.imageUrlsSubject.value.has(id);
}
public watch(): Observable<Map<number, string>> {
return this.imageUrlsSubject.asObservable();
}
}
现在,您可以在代码的其他地方订阅地图中的任何更改,您可以通过管道传递它,传递 pipe/observable,...
我正在学习angular。当谈到使用服务进行数据共享时,许多人建议我们应该使用Subject like BehaviorSubject。 但是我们应该一直这样做吗?
@Injectable({
providedIn: 'root'
})
export class DataService {
private imageUrls = new Map<number, string>();
public imageUrlsSubject = new BehaviorSubject(this.imageUrls);
public size(): number {
return this.imageUrls.size;
}
public set(id: number, url: string): void {
this.imageUrls.set(id, url);
this.imageUrlsSubject.next(this.imageUrls);
}
public get(id: number): string {
return this.imageUrls.get(id);
}
public has(id: number): boolean {
return this.imageUrls.has(id);
}
}
我按照这种做法写了一个这样的服务。这让我想知道:我们真的需要 Subject 吗?在另一个组件只需要使用 DOM 中的地图的情况下,我可以 摆脱 imageUrlsSubject 吗?
<img
*ngIf="dataService.has(row.id)"
[src]="dataService.get(row.id).url">
在另一个组件中,我可能只需要调用 dogDataService.set 来更新地图。
this.dataService.set(id, url);
如果去掉 Subject,会不会带来一些潜在的弊端?
谢谢!
你只是在内部使用你的 BehaviorSubject,但你的 getter 并不依赖它。您当前的服务与其消费者完全同步,"yes",您现在编程的方式 imageUrlsSubject
并不是真正必要的。
使用 Subject 的真正优势在于您可以将其作为 Observable 提供给其他地方!人们不再只能访问 imageUrls
的当前值,而是可以访问 imageUrls 的当前值和所有未来值!他们被赋予了流而不是快照。
然后您有 3 个设计选项:
- 总是return一个Observable。如果人们想要快照,他们必须通过管道传输
take(1)
。 - 始终 return 一个 Observable,但添加一个 shorthand 函数
snap
,return 是当前值。 - 总是 return 一个快照(就像它当前在您的代码中所做的那样)并添加一个
watch
函数,该函数 return 是一个 Observable。
我会更进一步说你不应该保留一个单独的 imageUrls
属性 而应该依赖 imageUrlsSubject.value
(仅用于 BehaviorSubjects)。我只是推荐这个,这样你 A) 不太可能忘记 subject.next(newValue)
当你改变你的价值 B) 再次提醒你你应该使用你的主题;p
这里是保持 get
默认同步行为并添加异步 watch
.
@Injectable({
providedIn: 'root'
})
export class DataService {
public imageUrlsSubject = new BehaviorSubject(new Map<number, string>());
public size(): number {
return this.imageUrlsSubject.value.size;
}
public set(id: number, url: string): void {
this.imageUrlsSubject.value.set(id,url);
this.imageUrlsSubject.next(this.imageUrlsSubject.value);
}
public get(id: number): string {
return this.imageUrlsSubject.value.get(id);
}
public has(id: number): boolean {
return this.imageUrlsSubject.value.has(id);
}
public watch(): Observable<Map<number, string>> {
return this.imageUrlsSubject.asObservable();
}
}
现在,您可以在代码的其他地方订阅地图中的任何更改,您可以通过管道传递它,传递 pipe/observable,...