angular - Angular12/rxjs:更新模板中的可观察数据并显示模板中的更改
问题描述
所以我有一个实时搜索,根据用户输入获取数据。
例子:
export class MyComponent implements OnInit {
constructor(private httpHandler: HttpHandlerService) { }
defaultSearchParams: SearchParams = { search: 'bla' }
searchParams = new BehaviorSubject<SearchParams>(this.defaultSearchParams);
myData$?: Observable<PageObjects<MyDataObject>>;
ngOnInit(): void {
this.myData$ = this.searchParams.pipe(
debounceTime(300),
switchMap((searchParams: SearchParams) => this.fetchMyData(searchParams)),
);
}
fetchMyData(searchParams: SearchParams): Observable<MyDataObject> {
return this.httpHandler.getMyData(searchParams);
}
}
我的模板显示数据:
<div *ngIf="(myData$ | async) as resultset$">
<div *ngIf="resultset$.elements && resultset$.elements.length">
<div *ngFor="let dataObject of resultset$.elements">
ID: {{dataObject.id}}, name {{dataObject.name}}, status {{dataObject.status}}
</div>
</div>
</div>
好吧,挑战来了:在我的模板中,我希望能够更改数据(即新名称、新状态)。
使用像我这样的可观察对象时,如何在模板中反映这些更改的数据?
期望结果的样本:
<div *ngIf="(myData$ | async) as resultset$">
<div *ngIf="resultset$.elements && resultset$.elements.length">
<div *ngFor="let dataObject of resultset$.elements">
ID: {{dataObject.id}}, name {{dataObject.name}}, status {{dataObject.status}}
<button (click)="changeStatus(dataObject)" type="button">Change status</button>
</div>
</div>
</div>
changeStatus(MyDataObject dataObject) {
this.httpHandler.changeStatusOfObject(dataObject, 'newStatus')
.subscribe(newDataObject => //WHERE should I put the newDataObject to, to show the new value in the template???);
}
解决方案
尝试更改changeStatus
函数以将更改推送到预定义的BehaviorSubject
changes$
,与 searchParams observable 结合形成myData$
observable。
您可以尝试以下方法:
changes$ = new BehaviorSubject<MyDataObject[]>([]);
ngOnInit(): void {
this.myData$ = combineLatest([
this.searchParams.pipe(
debounceTime(300),
switchMap((searchParams: SearchParams) =>
this.fetchMyData(searchParams)
)
),
this.changes$,
]).pipe(
map(([data, changes]) => {
if (changes?.length && data?.elements) {
changes.forEach((changedItem) => {
const ndx = data.elements.findIndex(
(item) => item.id === changedItem.id
);
if (ndx !== -1) data.elements[ndx] = changedItem;
});
}
return data;
})
);
}
changeStatus(dataObject: MyDataObject) {
this.httpHandler
.changeStatusOfObject(dataObject, 'newStatus')
// take one value from this observable and then complete it, to avoid memory leak
.pipe(take(1))
.subscribe((newDataObject) => {
// push the newDataObject to the chagnes$ subject.
this.changes$.next([newDataObject]);
});
}
推荐阅读
- python - RuntimeError:没有可用的 CUDA GPU
- protractor - 如何获得具有 ng-bulding 类的跨度值?
- javascript - 使用带有 create.js 脚本的“onclick”时,两个图像播放相同的声音?
- go - 如何找出golang SSA函数返回类型
- java - maven ProGuard 插件混淆失败 - 在类路径中找不到 ProGuard (proguard.ProGuard)
- python-3.x - 混合阿拉伯语+英文格式的日期需要在python中翻译成全英文
- c++ - 当 c++ 中取消引用的变量类型具有 '&' 或没有 '&' 时有什么区别?
- javascript - Javascript 下拉菜单只能使用一次
- kubernetes - 无法通过 AWS VPN 访问 GCP kubernetes 服务子网
- c++ - c++ "()" 运算符是如何重载的?