Angular & NgRx-Data 更新和订阅问题
Angular & NgRx-Data update & subscription issue
我正在使用 Angular 11 & NgRx-Data 10.1.2。我正在使用智能 component/dumb 组件模式。
在我的 'list' 视图中,当我 select 一个项目时,我路由到传递项目 ID 的详细信息页面。
在我的详情页,我订阅了实体服务getByKey()
this.siteEntityService.getByKey(this.siteId).subscribe((site: Site) => {
this.site = site;
});
这是 SiteEntityService:
import { Injectable } from '@angular/core';
import { EntityCollectionServiceBase, EntityCollectionServiceElementsFactory } from '@ngrx/data';
import { Site } from 'src/app/models/site.model';
@Injectable({ providedIn: 'root' })
export class SiteEntityService extends EntityCollectionServiceBase<Site> {
constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
super('Site', serviceElementsFactory);
}
}
点击'edit'时,我以模式打开编辑组件:
openEditModal(){
this.showingModal = true;
this.modalRef = this.modalService.open(SiteEditShellComponent);
this.modalRef.componentInstance.site = this.site;
}
在编辑组件中,当表单被提交时被点击:
formSubmitted(form: any) {
let updatedSite = { ...this.site };
updatedSite.name = form.siteName;
this.siteEntityService.update(updatedSite).subscribe((x: Site) => {
this.site = x;
this.activeModal.dismiss();
})
}
更新后,如果我调查商店,我可以看到实体已正确更新,但是,在模式关闭后,显示页面上的订阅不会更新,尽管商店(和数据库)正在更新。
那么我哪里错了?如何让展示页面刷新数据?
根据@Fiber 的回答进行编辑:
现在可以使用了,但是由于订阅返回的是项目数组,这意味着我必须在数组中搜索正确的项目,这似乎不太理想。
loadSite() {
let sites$ = this.siteEntityService.store.select((new EntitySelectorsFactory().create<Site>('Site')).selectEntities);
this.subscriptions.add(
sites$.pipe(
map((sites: Site[]) => {
return sites.find((site: Site) => site.id === this.siteId);
})
).subscribe((site: Site) => {
this.site = site;
})
);
this.siteEntityService.getByKey(this.siteId).subscribe((site: Site) => {
this.site = site;
});
}
从后端检索数据时只会触发一次:
this.siteEntityService.getByKey(this.siteId).subscribe((site: Site) => {
this.site = site;
});
该方法连接到数据检索方法,而不是您要查找的实体存储。
您应该制作一个直接连接到商店的可观察对象(ngrx/data 为您提供了一个 EntitySelectorsFactory 来执行此操作)并监听更改。
// this is gonna fire every time you update the store with new 'Site' items
sites$ = this.store.select((new EntitySelectorsFactory().create<Site>('Site')).selectEntities);
sites$.subscribe((sites: Site[]) => {
this.site = sites.find(s => s.id === this.siteId);
});
// this will trigger the initial load
this.siteEntityService.getByKey(this.siteId);
显然订阅应该在组件销毁时终止,但为简洁起见跳过了那部分。
我正在使用 Angular 11 & NgRx-Data 10.1.2。我正在使用智能 component/dumb 组件模式。
在我的 'list' 视图中,当我 select 一个项目时,我路由到传递项目 ID 的详细信息页面。
在我的详情页,我订阅了实体服务getByKey()
this.siteEntityService.getByKey(this.siteId).subscribe((site: Site) => {
this.site = site;
});
这是 SiteEntityService:
import { Injectable } from '@angular/core';
import { EntityCollectionServiceBase, EntityCollectionServiceElementsFactory } from '@ngrx/data';
import { Site } from 'src/app/models/site.model';
@Injectable({ providedIn: 'root' })
export class SiteEntityService extends EntityCollectionServiceBase<Site> {
constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
super('Site', serviceElementsFactory);
}
}
点击'edit'时,我以模式打开编辑组件:
openEditModal(){
this.showingModal = true;
this.modalRef = this.modalService.open(SiteEditShellComponent);
this.modalRef.componentInstance.site = this.site;
}
在编辑组件中,当表单被提交时被点击:
formSubmitted(form: any) {
let updatedSite = { ...this.site };
updatedSite.name = form.siteName;
this.siteEntityService.update(updatedSite).subscribe((x: Site) => {
this.site = x;
this.activeModal.dismiss();
})
}
更新后,如果我调查商店,我可以看到实体已正确更新,但是,在模式关闭后,显示页面上的订阅不会更新,尽管商店(和数据库)正在更新。
那么我哪里错了?如何让展示页面刷新数据?
根据@Fiber 的回答进行编辑:
现在可以使用了,但是由于订阅返回的是项目数组,这意味着我必须在数组中搜索正确的项目,这似乎不太理想。
loadSite() {
let sites$ = this.siteEntityService.store.select((new EntitySelectorsFactory().create<Site>('Site')).selectEntities);
this.subscriptions.add(
sites$.pipe(
map((sites: Site[]) => {
return sites.find((site: Site) => site.id === this.siteId);
})
).subscribe((site: Site) => {
this.site = site;
})
);
this.siteEntityService.getByKey(this.siteId).subscribe((site: Site) => {
this.site = site;
});
}
从后端检索数据时只会触发一次:
this.siteEntityService.getByKey(this.siteId).subscribe((site: Site) => {
this.site = site;
});
该方法连接到数据检索方法,而不是您要查找的实体存储。
您应该制作一个直接连接到商店的可观察对象(ngrx/data 为您提供了一个 EntitySelectorsFactory 来执行此操作)并监听更改。
// this is gonna fire every time you update the store with new 'Site' items
sites$ = this.store.select((new EntitySelectorsFactory().create<Site>('Site')).selectEntities);
sites$.subscribe((sites: Site[]) => {
this.site = sites.find(s => s.id === this.siteId);
});
// this will trigger the initial load
this.siteEntityService.getByKey(this.siteId);
显然订阅应该在组件销毁时终止,但为简洁起见跳过了那部分。