英文:
Manually update observable using Angular's async pipe
问题
私有主题 = 新的 BehaviorSubject<Thing[]>([]);
公共 thingsData$: 可观察的<Thing[]>;
// 这段代码首次运行时将执行 HTTP GET
// 但如果有任何进一步的更改,下一个() 将更新模板中的异步管道。
public ngOnInit(): 无效 {
this.thingsData$ = this.subject.asObservable().pipe(
switchMap((things: Thing[]) => {
if (things.length) {
return of(things);
}
return this.thingService.getThings();
})
);
}
// 我不确定这最终是否是最佳方法
// 执行此部分,但它说明了使用 next() 的用法
public createThing(newThing: Thing, existingThings: Thing[]): 无效 {
this.thingService.saveThing(newThing)
.subscribe((savedThing: Thing) => {
subject.next(
existingThings.push(newThing);
);
});
}
英文:
I have an HTTP GET call that returns a list of things. I also have a POST that saves a new record and then returns the saved record. Using observables and the Angular async pipe, after POSTing a new record, I would like to merely append that new record to the list instead of doing a whole new GET to update the list.
private subject = new BehaviorSubject<Thing[]>([]);
public thingsData$: Observable<Thing[]>;
// The first run through this code will do the HTTP GET
// but then if there are any further alterations, the
// next() will update the async pipe in the template.
public ngOnInit(): void {
this.thingsData$ = this.subject.asObservable().pipe(
switchMap((things: Thing[]) => {
if (things.length) {
return of(things);
}
return this.thingService.getThings();
})
);
}
// I'm not sure if this will ultimately be the best way
// to do this part but it illustrates the use of next()
public createThing(newThing: Thing, existingThings: Thing[]): void {
this.thingService.saveThing(newThing)
.subscribe((savedThing: Thing) => {
subject.next(
existingThings.push(newThing);
);
});
}
答案1
得分: 0
不需要使用switchMap
,只需将行为主题命名为thingsData$
,然后直接订阅服务。
this.thingService.getThings().subscribe(things => { this.thingsData$.next(things); });
当你使用可观察对象进行更新时,希望它发出一个新对象,不应该修改现有对象。使可观察对象发出新对象的标准方法是使用展开运算符。数组上的展开运算符用法如下 [...previousArray, newValue]
。行为主题已经包含了现有的数据,所以可以这样更新:
public createThing(newThing: Thing): void {
this.thingService.saveThing(newThing).subscribe((savedThing: Thing) => {
this.thingsData$.next([...this.thingsData$.value, newThing]);
});
}
英文:
There is no need for your switchMap, just call the behavior subject thingsData$ and subscribe straight to the service.
this.thingService.getThings().subscribe(things => { this.thingsData$.next(things); });
When you update with an observable you want it to emit a new object, you shouldn't mutate an existing object. The standard way of making an observable emit a new object is to use the spread operator. The spread operator on an array is used like [...previousArray, newValue]
. The behavior subject already contains the exisiting things so you can update like.
public createThing(newThing: Thing): void {
this.thingService.saveThing(newThing).subscribe((savedThing: Thing) => {
this.thingsData$.next([...this.thingsData$.value, newThing]);
}
}
答案2
得分: 0
以下是翻译好的部分:
-
You can create a single observable from two sources using
merge
.- 你可以使用
merge
从两个来源创建一个单一的可观察对象。
- 你可以使用
-
Let's call the two sources
existingThings$
andcreatedThing$
.- 让我们称这两个来源为
existingThings$
和createdThing$
。
- 让我们称这两个来源为
-
We can use the
scan
operator to combine the emitted things from both sources into a single collection.- 我们可以使用
scan
运算符将来自两个来源的发射对象合并为一个单一集合。
- 我们可以使用
-
Here's a working StackBlitz demo.
- 这里有一个可运行的 StackBlitz 演示。
英文:
You can create a single observable from two sources using merge
.
Let's call the two sources existingThings$
and createdThing$
.
We can use the scan
operator to combine the emitted things from both sources into a single collection.
private existingThings$ = this.thingService.getThings();
private createdThing$ = new Subject<Thing>();
things$ = merge(this.existingThings$, this.createdThing$).pipe(
scan((previous, current) => previous.concat(current), [] as Thing[])
);
createThing(newThing: Thing) {
this.thingService.saveThing(newThing).subscribe(
createdThing => this.createdThing$.next(createdThing)
);
}
Here's a working StackBlitz demo.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论